Psi2Ir: Create instance initializer calls in enum class constructors
This commit is contained in:
committed by
max-kammerer
parent
83edc7fa73
commit
f8779ddf9d
-30
@@ -125,9 +125,6 @@ class EnumClassConstructorTransformer(val context: CommonBackendContext, private
|
|||||||
private val loweredEnumConstructors = HashMap<IrConstructorSymbol, IrConstructor>()
|
private val loweredEnumConstructors = HashMap<IrConstructorSymbol, IrConstructor>()
|
||||||
|
|
||||||
fun transform(): List<IrDeclaration> {
|
fun transform(): List<IrDeclaration> {
|
||||||
// Make sure InstanceInitializer exists
|
|
||||||
insertInstanceInitializer()
|
|
||||||
|
|
||||||
// Add `name` and `ordinal` parameters to enum class constructors
|
// Add `name` and `ordinal` parameters to enum class constructors
|
||||||
lowerEnumConstructorsSignature()
|
lowerEnumConstructorsSignature()
|
||||||
|
|
||||||
@@ -149,33 +146,6 @@ class EnumClassConstructorTransformer(val context: CommonBackendContext, private
|
|||||||
return listOf(irClass)
|
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() {
|
private fun lowerEnumConstructorsSignature() {
|
||||||
irClass.declarations.transform { declaration ->
|
irClass.declarations.transform { declaration ->
|
||||||
if (declaration is IrConstructor) {
|
if (declaration is IrConstructor) {
|
||||||
|
|||||||
-30
@@ -69,7 +69,6 @@ private class EnumClassLowering(val context: JvmBackendContext) : ClassLoweringP
|
|||||||
private lateinit var valueOfFunction: IrFunction
|
private lateinit var valueOfFunction: IrFunction
|
||||||
|
|
||||||
fun run() {
|
fun run() {
|
||||||
insertInstanceInitializer()
|
|
||||||
assignOrdinalsToEnumEntries()
|
assignOrdinalsToEnumEntries()
|
||||||
lowerEnumConstructors(irClass)
|
lowerEnumConstructors(irClass)
|
||||||
lowerEnumEntries()
|
lowerEnumEntries()
|
||||||
@@ -77,35 +76,6 @@ private class EnumClassLowering(val context: JvmBackendContext) : ClassLoweringP
|
|||||||
lowerEnumClassBody()
|
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() {
|
private fun assignOrdinalsToEnumEntries() {
|
||||||
var ordinal = 0
|
var ordinal = 0
|
||||||
irClass.declarations.forEach {
|
irClass.declarations.forEach {
|
||||||
|
|||||||
@@ -54,11 +54,15 @@ fun ResolvedCall<*>.isValueArgumentReorderingRequired(): Boolean {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun KtSecondaryConstructor.isConstructorDelegatingToSuper(bindingContext: BindingContext): Boolean {
|
fun KtSecondaryConstructor.isConstructorDelegatingToSuper(bindingContext: BindingContext): Boolean {
|
||||||
val delegatingResolvedCall = getDelegationCall().getResolvedCall(bindingContext) ?: return false
|
|
||||||
val constructorDescriptor = bindingContext.get(BindingContext.CONSTRUCTOR, this) ?: return false
|
val constructorDescriptor = bindingContext.get(BindingContext.CONSTRUCTOR, this) ?: return false
|
||||||
val ownerClassDescriptor = constructorDescriptor.containingDeclaration
|
val delegatingResolvedCall = getDelegationCall().getResolvedCall(bindingContext)
|
||||||
val targetClassDescriptor = delegatingResolvedCall.resultingDescriptor.containingDeclaration
|
return if (delegatingResolvedCall != null) {
|
||||||
return targetClassDescriptor != ownerClassDescriptor
|
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) =
|
inline fun ClassDescriptor.findFirstFunction(name: String, predicate: (CallableMemberDescriptor) -> Boolean) =
|
||||||
|
|||||||
Reference in New Issue
Block a user