diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/IrElementToJsStatementTransformer.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/IrElementToJsStatementTransformer.kt index 53ce402344b..d3619167f41 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/IrElementToJsStatementTransformer.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/IrElementToJsStatementTransformer.kt @@ -15,6 +15,7 @@ import org.jetbrains.kotlin.ir.symbols.IrReturnableBlockSymbol import org.jetbrains.kotlin.ir.types.isAny import org.jetbrains.kotlin.ir.util.constructedClassType import org.jetbrains.kotlin.ir.util.file +import org.jetbrains.kotlin.ir.util.render import org.jetbrains.kotlin.js.backend.ast.* @Suppress("PARAMETER_NAME_CHANGED_ON_OVERRIDE") @@ -64,8 +65,11 @@ class IrElementToJsStatementTransformer : BaseIrElementToJsNodeTransformer JsStatement): JsStatement { if (this is IrWhen) { - val stmtTransformer = { stmt: JsStatement -> transformer((stmt as JsExpressionStatement).expression) } - SwitchOptimizer(context, stmtTransformer).tryOptimize(this)?.let { return it } + val stmtTransformer = { stmt: JsStatement -> + assert(stmt is JsExpressionStatement) { "${render()} is not a statement $stmt" } + transformer((stmt as JsExpressionStatement).expression) + } + SwitchOptimizer(context, isExpression = true, stmtTransformer).tryOptimize(this)?.let { return it } } return transformer(accept(IrElementToJsExpressionTransformer(), context)) @@ -112,7 +116,7 @@ class IrElementToJsStatementTransformer : BaseIrElementToJsNodeTransformer JsStatement) { +class SwitchOptimizer(private val context: JsGenerationContext, private val isExpression: Boolean, private val lastStatementTransformer: (JsStatement) -> JsStatement) { // TODO: reimplement optimization on top of IR - constructor(context: JsGenerationContext) : this(context, { it }) + constructor(context: JsGenerationContext) : this(context, isExpression = false, { it }) private val jsEqeqeq = context.staticContext.backendContext.intrinsics.jsEqeqeq private val jsEqeq = context.staticContext.backendContext.intrinsics.jsEqeq @@ -144,19 +144,27 @@ class SwitchOptimizer(private val context: JsGenerationContext, private val last JsDefault().also { jsCases += it } } - val jsBody = case.body.accept(stmtTransformer, context).asBlock() - var lastStatement = jsBody.statements.lastOrNull() + val lastStatement = if (isExpression) { + val expression = case.body.accept(exprTransformer, context).makeStmt() + val lastStatement = lastStatementTransformer(expression) + jsCase.statements += lastStatement + lastStatement + } else { + val jsBody = case.body.accept(stmtTransformer, context).asBlock() + var lastStatement = jsBody.statements.lastOrNull() - if (lastStatement != null) { - lastStatement = lastStatementTransformer(lastStatement) - jsBody.statements[jsBody.statements.lastIndex] = lastStatement + if (lastStatement != null) { + lastStatement = lastStatementTransformer(lastStatement) + jsBody.statements[jsBody.statements.lastIndex] = lastStatement + } + + jsCase.statements += jsBody.statements + lastStatement } if (lastStatement !is JsBreak && lastStatement !is JsContinue && lastStatement !is JsReturn && lastStatement !is JsThrow) { - jsBody.statements += JsBreak() + jsCase.statements += JsBreak() } - - jsCase.statements += jsBody.statements } return JsSwitch(jsExpr, jsCases)