From 3fa33b5969289d4c70d5e2fdedc2adf83a4309c2 Mon Sep 17 00:00:00 2001 From: Dmitry Petrov Date: Mon, 12 Sep 2016 16:49:12 +0300 Subject: [PATCH] Fix compound assignment on arbitrary expression in LHS (with a convention compound assignment operator defined). --- .../psi2ir/generators/AssignmentGenerator.kt | 2 +- .../intermediate/OnceExpressionValue.kt | 9 ++++- .../psi2ir/intermediate/VariableLValue.kt | 3 +- .../augmentedAssignmentWithExpression.kt | 21 ++++++++++++ .../augmentedAssignmentWithExpression.txt | 33 +++++++++++++++++++ .../kotlin/ir/IrTextTestCaseGenerated.java | 6 ++++ 6 files changed, 70 insertions(+), 4 deletions(-) create mode 100644 compiler/testData/ir/irText/expressions/augmentedAssignmentWithExpression.kt create mode 100644 compiler/testData/ir/irText/expressions/augmentedAssignmentWithExpression.txt 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 6e45975e883..49e6663888f 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 @@ -127,7 +127,7 @@ class AssignmentGenerator(statementGenerator: StatementGenerator) : StatementGen is VariableDescriptor -> VariableLValue(ktLeft.startOffset, ktLeft.endOffset, descriptor, operator) else -> - TODO("Other cases of LHS") + OnceExpressionValue(statementGenerator.generateExpression(ktLeft)) } } diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/intermediate/OnceExpressionValue.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/intermediate/OnceExpressionValue.kt index 8a690050153..cb0667a4017 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/intermediate/OnceExpressionValue.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/intermediate/OnceExpressionValue.kt @@ -21,7 +21,7 @@ import org.jetbrains.kotlin.ir.util.render import org.jetbrains.kotlin.psi2ir.generators.CallGenerator import org.jetbrains.kotlin.types.KotlinType -class OnceExpressionValue(val irExpression: IrExpression) : IntermediateValue { +class OnceExpressionValue(val irExpression: IrExpression) : LValue, AssignmentReceiver { private var instantiated = false override fun load(): IrExpression { @@ -31,4 +31,11 @@ class OnceExpressionValue(val irExpression: IrExpression) : IntermediateValue { } override val type: KotlinType get() = irExpression.type + + override fun store(irExpression: IrExpression): IrExpression { + throw AssertionError("Expression value ${irExpression.render()} can't be used in store operation") + } + + override fun assign(withLValue: (LValue) -> IrExpression): IrExpression = + withLValue(this) } \ No newline at end of file diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/intermediate/VariableLValue.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/intermediate/VariableLValue.kt index 561177beca9..0492f416f86 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/intermediate/VariableLValue.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/intermediate/VariableLValue.kt @@ -40,8 +40,7 @@ class VariableLValue( IrGetVariableImpl(startOffset, endOffset, descriptor, irOperator) override fun store(irExpression: IrExpression): IrExpression = - IrSetVariableImpl(startOffset, endOffset, descriptor, - irExpression, irOperator) + IrSetVariableImpl(startOffset, endOffset, descriptor, irExpression, irOperator) override fun assign(withLValue: (LValue) -> IrExpression): IrExpression = withLValue(this) diff --git a/compiler/testData/ir/irText/expressions/augmentedAssignmentWithExpression.kt b/compiler/testData/ir/irText/expressions/augmentedAssignmentWithExpression.kt new file mode 100644 index 00000000000..caaa27d0ffc --- /dev/null +++ b/compiler/testData/ir/irText/expressions/augmentedAssignmentWithExpression.kt @@ -0,0 +1,21 @@ +class Host { + operator fun plusAssign(x: Int) {} + + fun test1() { + this += 1 + } +} + +fun foo() = Host() + +fun Host.test2() { + this += 1 +} + +fun test3() { + foo() += 1 +} + +fun test4(a: () -> Host) { + a() += 1 +} diff --git a/compiler/testData/ir/irText/expressions/augmentedAssignmentWithExpression.txt b/compiler/testData/ir/irText/expressions/augmentedAssignmentWithExpression.txt new file mode 100644 index 00000000000..d15f90f7c4c --- /dev/null +++ b/compiler/testData/ir/irText/expressions/augmentedAssignmentWithExpression.txt @@ -0,0 +1,33 @@ +FILE /augmentedAssignmentWithExpression.kt + CLASS CLASS Host + CONSTRUCTOR public constructor Host() + BLOCK_BODY + DELEGATING_CONSTRUCTOR_CALL 'constructor Any()' + INSTANCE_INITIALIZER_CALL classDescriptor='Host' + FUN public final operator fun plusAssign(x: kotlin.Int): kotlin.Unit + BLOCK_BODY + FUN public final fun test1(): kotlin.Unit + BLOCK_BODY + CALL 'plusAssign(Int): Unit' type=kotlin.Unit operator=PLUSEQ + $this: THIS of 'Host' type=Host + x: CONST Int type=kotlin.Int value='1' + FUN public fun foo(): Host + BLOCK_BODY + RETURN type=kotlin.Nothing from='foo(): Host' + CALL 'constructor Host()' type=Host operator=null + FUN public fun Host.test2(): kotlin.Unit + BLOCK_BODY + CALL 'plusAssign(Int): Unit' type=kotlin.Unit operator=PLUSEQ + $this: $RECEIVER of 'test2() on Host: Unit' type=Host + x: CONST Int type=kotlin.Int value='1' + FUN public fun test3(): kotlin.Unit + BLOCK_BODY + CALL 'plusAssign(Int): Unit' type=kotlin.Unit operator=PLUSEQ + $this: CALL 'foo(): Host' type=Host operator=null + x: CONST Int type=kotlin.Int value='1' + FUN public fun test4(a: () -> Host): kotlin.Unit + BLOCK_BODY + CALL 'plusAssign(Int): Unit' type=kotlin.Unit operator=PLUSEQ + $this: CALL 'invoke(): Host' type=Host operator=INVOKE + $this: GET_VAR 'value-parameter a: () -> Host' type=() -> Host operator=VARIABLE_AS_FUNCTION + x: CONST Int type=kotlin.Int value='1' diff --git a/compiler/tests/org/jetbrains/kotlin/ir/IrTextTestCaseGenerated.java b/compiler/tests/org/jetbrains/kotlin/ir/IrTextTestCaseGenerated.java index d32b065fe5a..7aae1d5b4f4 100644 --- a/compiler/tests/org/jetbrains/kotlin/ir/IrTextTestCaseGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/ir/IrTextTestCaseGenerated.java @@ -310,6 +310,12 @@ public class IrTextTestCaseGenerated extends AbstractIrTextTestCase { doTest(fileName); } + @TestMetadata("augmentedAssignmentWithExpression.kt") + public void testAugmentedAssignmentWithExpression() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/expressions/augmentedAssignmentWithExpression.kt"); + doTest(fileName); + } + @TestMetadata("badBreakContinue.kt") public void testBadBreakContinue() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/expressions/badBreakContinue.kt");