Psi2Ir: Create instance initializer calls in enum class constructors

This commit is contained in:
Steven Schäfer
2020-01-09 14:03:42 +01:00
committed by max-kammerer
parent 83edc7fa73
commit f8779ddf9d
3 changed files with 8 additions and 64 deletions
@@ -125,9 +125,6 @@ class EnumClassConstructorTransformer(val context: CommonBackendContext, private
private val loweredEnumConstructors = HashMap<IrConstructorSymbol, IrConstructor>()
fun transform(): List<IrDeclaration> {
// Make sure InstanceInitializer exists
insertInstanceInitializer()
// Add `name` and `ordinal` parameters to enum class constructors
lowerEnumConstructorsSignature()
@@ -149,33 +146,6 @@ class EnumClassConstructorTransformer(val context: CommonBackendContext, private
return listOf(irClass)
}
private fun insertInstanceInitializer() {
irClass.transformChildrenVoid(object : IrElementTransformerVoid() {
override fun visitClass(declaration: IrClass) = declaration
override fun visitConstructor(declaration: IrConstructor): IrStatement {
declaration.transformChildrenVoid(this)
val blockBody = declaration.body as IrBlockBody
if (!blockBody.statements.any { it is IrInstanceInitializerCall }) {
blockBody.statements.transformFlat {
if (it is IrEnumConstructorCall)
listOf(
it, IrInstanceInitializerCallImpl(
declaration.startOffset, declaration.startOffset,
irClass.symbol, context.irBuiltIns.unitType
)
)
else null
}
}
return declaration
}
})
}
private fun lowerEnumConstructorsSignature() {
irClass.declarations.transform { declaration ->
if (declaration is IrConstructor) {
@@ -69,7 +69,6 @@ private class EnumClassLowering(val context: JvmBackendContext) : ClassLoweringP
private lateinit var valueOfFunction: IrFunction
fun run() {
insertInstanceInitializer()
assignOrdinalsToEnumEntries()
lowerEnumConstructors(irClass)
lowerEnumEntries()
@@ -77,35 +76,6 @@ private class EnumClassLowering(val context: JvmBackendContext) : ClassLoweringP
lowerEnumClassBody()
}
// Make sure that an instance initializer call exists, so that field initialization code will be generated.
// TODO: This function is identical to the one used in the JS lowerings. Share them.
private fun insertInstanceInitializer() {
irClass.transformChildrenVoid(object : IrElementTransformerVoid() {
override fun visitClass(declaration: IrClass) = declaration
override fun visitConstructor(declaration: IrConstructor): IrStatement {
declaration.transformChildrenVoid(this)
val blockBody = declaration.body as IrBlockBody
if (!blockBody.statements.any { it is IrInstanceInitializerCall }) {
blockBody.statements.transformFlat {
if (it is IrEnumConstructorCall)
listOf(
it, IrInstanceInitializerCallImpl(
declaration.startOffset, declaration.startOffset,
irClass.symbol, context.irBuiltIns.unitType
)
)
else null
}
}
return declaration
}
})
}
private fun assignOrdinalsToEnumEntries() {
var ordinal = 0
irClass.declarations.forEach {
@@ -54,11 +54,15 @@ fun ResolvedCall<*>.isValueArgumentReorderingRequired(): Boolean {
}
fun KtSecondaryConstructor.isConstructorDelegatingToSuper(bindingContext: BindingContext): Boolean {
val delegatingResolvedCall = getDelegationCall().getResolvedCall(bindingContext) ?: return false
val constructorDescriptor = bindingContext.get(BindingContext.CONSTRUCTOR, this) ?: return false
val ownerClassDescriptor = constructorDescriptor.containingDeclaration
val targetClassDescriptor = delegatingResolvedCall.resultingDescriptor.containingDeclaration
return targetClassDescriptor != ownerClassDescriptor
val delegatingResolvedCall = getDelegationCall().getResolvedCall(bindingContext)
return if (delegatingResolvedCall != null) {
val ownerClassDescriptor = constructorDescriptor.containingDeclaration
val targetClassDescriptor = delegatingResolvedCall.resultingDescriptor.containingDeclaration
targetClassDescriptor != ownerClassDescriptor
} else {
constructorDescriptor.constructedClass.kind == ClassKind.ENUM_CLASS
}
}
inline fun ClassDescriptor.findFirstFunction(name: String, predicate: (CallableMemberDescriptor) -> Boolean) =