From 535eea7f48386e22ee2be98be15970b59723f70d Mon Sep 17 00:00:00 2001 From: Roman Artemev Date: Wed, 31 Oct 2018 01:23:56 +0300 Subject: [PATCH] [JS IR BE] fix enum initialization --- .../ir/backend/js/lower/EnumClassLowering.kt | 42 ++++++++++++++++--- .../box/secondaryConstructors/enums.kt | 1 - 2 files changed, 37 insertions(+), 6 deletions(-) diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/EnumClassLowering.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/EnumClassLowering.kt index ba41882f6dd..2afd536766a 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/EnumClassLowering.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/EnumClassLowering.kt @@ -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 { + // 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() @@ -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])) diff --git a/compiler/testData/codegen/box/secondaryConstructors/enums.kt b/compiler/testData/codegen/box/secondaryConstructors/enums.kt index 7d731d96281..3b0bdf8007e 100644 --- a/compiler/testData/codegen/box/secondaryConstructors/enums.kt +++ b/compiler/testData/codegen/box/secondaryConstructors/enums.kt @@ -1,5 +1,4 @@ // IGNORE_BACKEND: JVM_IR -// IGNORE_BACKEND: JS_IR enum class A1(val prop1: String) { X("asd"), Y() {