[JS IR BE] fix enum initialization

This commit is contained in:
Roman Artemev
2018-10-31 01:23:56 +03:00
committed by romanart
parent b86e2e6dc0
commit 535eea7f48
2 changed files with 37 additions and 6 deletions
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
import org.jetbrains.kotlin.backend.common.lower.irBlockBody
import org.jetbrains.kotlin.backend.common.lower.irIfThen
import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
import org.jetbrains.kotlin.ir.backend.js.ir.JsIrBuilder
@@ -23,6 +24,7 @@ import org.jetbrains.kotlin.ir.declarations.impl.IrConstructorImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrFieldImpl
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrInstanceInitializerCallImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrVarargImpl
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
import org.jetbrains.kotlin.ir.symbols.IrValueParameterSymbol
@@ -106,6 +108,9 @@ class EnumClassTransformer(val context: JsIrBackendContext, private val irClass:
private val throwISESymbol = context.throwISEymbol
fun transform(): List<IrDeclaration> {
// Make sure InstanceInitializer exists
insertInstanceInitializer()
// Add `name` and `ordinal` parameters to enum class constructors
lowerEnumConstructorsSignature()
@@ -146,6 +151,33 @@ class EnumClassTransformer(val context: JsIrBackendContext, private val irClass:
return listOf(irClass) + entryInstances + listOf(entryInstancesInitializedVar, initEntryInstancesFun) + entryGetInstanceFuns
}
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 fixReferencesToConstructorParameters() {
val fromOldToNewParameter = mutableMapOf<IrValueParameterSymbol, IrValueParameter>()
@@ -158,7 +190,7 @@ class EnumClassTransformer(val context: JsIrBackendContext, private val irClass:
}
}
irClass.transformChildrenVoid(object: IrElementTransformerVoid() {
irClass.transformChildrenVoid(object : IrElementTransformerVoid() {
override fun visitGetValue(expression: IrGetValue): IrExpression {
fromOldToNewParameter[expression.symbol]?.let {
return builder.irGet(it)
@@ -322,13 +354,13 @@ class EnumClassTransformer(val context: JsIrBackendContext, private val irClass:
}
override fun visitDelegatingConstructorCall(expression: IrDelegatingConstructorCall): IrExpression {
var constructor = expression.symbol.owner
val constructorWasTransformed = constructor.symbol in loweredEnumConstructors
var delegatingConstructor = expression.symbol.owner
val constructorWasTransformed = delegatingConstructor.symbol in loweredEnumConstructors
if (constructorWasTransformed)
constructor = loweredEnumConstructors[constructor.symbol]!!
delegatingConstructor = loweredEnumConstructors[delegatingConstructor.symbol]!!
return builder.irDelegatingConstructorCall(constructor).apply {
return builder.irDelegatingConstructorCall(delegatingConstructor).apply {
var valueArgIdx = 0
for (i in 0..1) {
putValueArgument(valueArgIdx++, builder.irGet(constructor.valueParameters[i]))
@@ -1,5 +1,4 @@
// IGNORE_BACKEND: JVM_IR
// IGNORE_BACKEND: JS_IR
enum class A1(val prop1: String) {
X("asd"),
Y() {