diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/builders/IrBuilder.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/builders/IrBuilder.kt index 31b9b4fa517..e94881eb8ac 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/builders/IrBuilder.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/builders/IrBuilder.kt @@ -16,10 +16,13 @@ package org.jetbrains.kotlin.psi2ir.builders -import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.IrStatement +import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET import org.jetbrains.kotlin.ir.expressions.* +import org.jetbrains.kotlin.psi.KtElement +import org.jetbrains.kotlin.psi.psiUtil.endOffset +import org.jetbrains.kotlin.psi.psiUtil.startOffset import org.jetbrains.kotlin.psi2ir.generators.Generator import org.jetbrains.kotlin.psi2ir.generators.GeneratorContext import org.jetbrains.kotlin.psi2ir.generators.GeneratorWithScope @@ -81,6 +84,11 @@ class IrBlockBuilder( ) : IrStatementsBuilder(context, scope, startOffset, endOffset) { private val statements = ArrayList() + inline fun block(body: IrBlockBuilder.() -> Unit): IrBlock { + body() + return doBuild() + } + override fun addStatement(irStatement: IrStatement) { statements.add(irStatement) } @@ -100,3 +108,12 @@ fun T.at(startOffset: Int, endOffset: Int): T { this.endOffset = endOffset return this } + +inline fun GeneratorWithScope.irBlock(ktElement: KtElement? = null, operator: IrOperator? = null, resultType: KotlinType? = null, + body: IrBlockBuilder.() -> Unit +): IrExpression = + IrBlockBuilder(context, scope, + ktElement?.startOffset ?: UNDEFINED_OFFSET, + ktElement?.endOffset ?: UNDEFINED_OFFSET, + operator, resultType + ).block(body) \ No newline at end of file diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/AssignmentGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/AssignmentGenerator.kt index 5045d591a54..dab9bb64651 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/AssignmentGenerator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/AssignmentGenerator.kt @@ -21,13 +21,14 @@ import org.jetbrains.kotlin.descriptors.ConstructorDescriptor import org.jetbrains.kotlin.descriptors.PropertyDescriptor import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor import org.jetbrains.kotlin.descriptors.impl.SyntheticFieldDescriptor -import org.jetbrains.kotlin.ir.expressions.IrBlockImpl import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrOperator import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.endOffset import org.jetbrains.kotlin.psi.psiUtil.startOffset -import org.jetbrains.kotlin.psi2ir.defaultLoad +import org.jetbrains.kotlin.psi2ir.builders.defineTemporary +import org.jetbrains.kotlin.psi2ir.builders.irBlock +import org.jetbrains.kotlin.psi2ir.builders.irGet import org.jetbrains.kotlin.psi2ir.intermediate.* import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.calls.callUtil.isSafeCall @@ -72,22 +73,14 @@ class AssignmentGenerator(statementGenerator: StatementGenerator) : StatementGen val irAssignmentReceiver = generateAssignmentReceiver(ktBaseExpression, irOperator) return irAssignmentReceiver.assign { irLValue -> - val irBlock = IrBlockImpl(expression.startOffset, expression.endOffset, irLValue.type, irOperator) - - // VAR tmp = [lhs].inc() - val opCall = statementGenerator.pregenerateCall(opResolvedCall) - opCall.setExplicitReceiverValue(irLValue) - val irOpCall = CallGenerator(statementGenerator).generateCall(expression, opCall, irOperator) - val irTmp = statementGenerator.scope.createTemporaryVariable(irOpCall) - irBlock.addStatement(irTmp) - - // [lhs] = tmp - irBlock.addStatement(irLValue.store(irTmp.defaultLoad())) - - // ^ tmp - irBlock.addStatement(irTmp.defaultLoad()) - - irBlock + irBlock(expression, irOperator, irLValue.type) { + val opCall = statementGenerator.pregenerateCall(opResolvedCall) + opCall.setExplicitReceiverValue(irLValue) + val irOpCall = CallGenerator(statementGenerator).generateCall(expression, opCall, irOperator) + val temporary = defineTemporary(irOpCall) + +irLValue.store(irGet(temporary)) + +irGet(temporary) + } } } @@ -97,22 +90,14 @@ class AssignmentGenerator(statementGenerator: StatementGenerator) : StatementGen val irAssignmentReceiver = generateAssignmentReceiver(ktBaseExpression, irOperator) return irAssignmentReceiver.assign { irLValue -> - val irBlock = IrBlockImpl(expression.startOffset, expression.endOffset, irLValue.type, irOperator) - - // VAR tmp = [lhs] - val irTmp = scope.createTemporaryVariable(irLValue.load()) - irBlock.addStatement(irTmp) - - // [lhs] = tmp.inc() - val opCall = statementGenerator.pregenerateCall(opResolvedCall) - opCall.setExplicitReceiverValue(VariableLValue(irTmp)) - val irOpCall = CallGenerator(statementGenerator).generateCall(expression, opCall, irOperator) - irBlock.addStatement(irLValue.store(irOpCall)) - - // ^ tmp - irBlock.addStatement(irTmp.defaultLoad()) - - irBlock + irBlock(expression, irOperator, irLValue.type) { + val temporary = defineTemporary(irLValue.load()) + val opCall = statementGenerator.pregenerateCall(opResolvedCall) + opCall.setExplicitReceiverValue(VariableLValue(startOffset, endOffset, temporary)) + val irOpCall = CallGenerator(statementGenerator).generateCall(expression, opCall, irOperator) + +irLValue.store(irOpCall) + +irGet(temporary) + } } }