diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/BlockDecomposerLowering.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/BlockDecomposerLowering.kt index fe80b5b9e40..337857c44a1 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/BlockDecomposerLowering.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/BlockDecomposerLowering.kt @@ -14,9 +14,7 @@ import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.impl.* import org.jetbrains.kotlin.ir.types.IrType -import org.jetbrains.kotlin.ir.util.patchDeclarationParents -import org.jetbrains.kotlin.ir.util.transformDeclarationsFlat -import org.jetbrains.kotlin.ir.util.transformFlat +import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.visitors.IrElementTransformer import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid @@ -543,6 +541,40 @@ class BlockDecomposerTransformer(private val context: JsIrBackendContext) : IrEl return expression.run { IrCompositeImpl(startOffset, endOffset, type, origin, newStatements) } } + override fun visitDynamicMemberExpression(expression: IrDynamicMemberExpression): IrExpression { + expression.transformChildrenVoid(expressionTransformer) + + val composite = expression.receiver as? IrComposite ?: return expression + + return materializeLastExpression(composite) { + expression.apply { receiver = it } + } + } + + override fun visitDynamicOperatorExpression(expression: IrDynamicOperatorExpression): IrExpression { + expression.transformChildrenVoid(expressionTransformer) + + val oldArguments = listOf(expression.receiver) + expression.arguments + val compositeCount = oldArguments.count { it is IrComposite } + + if (compositeCount == 0) return expression + + val newStatements = mutableListOf() + val newArguments = mapArguments(oldArguments, compositeCount, newStatements) + + expression.receiver = newArguments[0] + ?: error("No new receiver in destructured composite for:\n${expression.dump()}") + + for (i in expression.arguments.indices) { + expression.arguments[i] = newArguments[i + 1] + ?: error("No argument #$i in destructured composite for:\n${expression.dump()}") + } + + newStatements.add(expression) + + return expression.run { IrCompositeImpl(startOffset, endOffset, type, null, newStatements) } + } + override fun visitContainerExpression(expression: IrContainerExpression): IrExpression { expression.run { if (statements.isEmpty()) return IrCompositeImpl(startOffset, endOffset, type, origin, listOf(unitValue)) }