Fix compound assignment on arbitrary expression in LHS
(with a convention compound assignment operator defined).
This commit is contained in:
committed by
Dmitry Petrov
parent
0cdf831bf0
commit
3fa33b5969
+1
-1
@@ -127,7 +127,7 @@ class AssignmentGenerator(statementGenerator: StatementGenerator) : StatementGen
|
|||||||
is VariableDescriptor ->
|
is VariableDescriptor ->
|
||||||
VariableLValue(ktLeft.startOffset, ktLeft.endOffset, descriptor, operator)
|
VariableLValue(ktLeft.startOffset, ktLeft.endOffset, descriptor, operator)
|
||||||
else ->
|
else ->
|
||||||
TODO("Other cases of LHS")
|
OnceExpressionValue(statementGenerator.generateExpression(ktLeft))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+8
-1
@@ -21,7 +21,7 @@ import org.jetbrains.kotlin.ir.util.render
|
|||||||
import org.jetbrains.kotlin.psi2ir.generators.CallGenerator
|
import org.jetbrains.kotlin.psi2ir.generators.CallGenerator
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
|
|
||||||
class OnceExpressionValue(val irExpression: IrExpression) : IntermediateValue {
|
class OnceExpressionValue(val irExpression: IrExpression) : LValue, AssignmentReceiver {
|
||||||
private var instantiated = false
|
private var instantiated = false
|
||||||
|
|
||||||
override fun load(): IrExpression {
|
override fun load(): IrExpression {
|
||||||
@@ -31,4 +31,11 @@ class OnceExpressionValue(val irExpression: IrExpression) : IntermediateValue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override val type: KotlinType get() = irExpression.type
|
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)
|
||||||
}
|
}
|
||||||
+1
-2
@@ -40,8 +40,7 @@ class VariableLValue(
|
|||||||
IrGetVariableImpl(startOffset, endOffset, descriptor, irOperator)
|
IrGetVariableImpl(startOffset, endOffset, descriptor, irOperator)
|
||||||
|
|
||||||
override fun store(irExpression: IrExpression): IrExpression =
|
override fun store(irExpression: IrExpression): IrExpression =
|
||||||
IrSetVariableImpl(startOffset, endOffset, descriptor,
|
IrSetVariableImpl(startOffset, endOffset, descriptor, irExpression, irOperator)
|
||||||
irExpression, irOperator)
|
|
||||||
|
|
||||||
override fun assign(withLValue: (LValue) -> IrExpression): IrExpression =
|
override fun assign(withLValue: (LValue) -> IrExpression): IrExpression =
|
||||||
withLValue(this)
|
withLValue(this)
|
||||||
|
|||||||
@@ -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
|
||||||
|
}
|
||||||
+33
@@ -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'
|
||||||
@@ -310,6 +310,12 @@ public class IrTextTestCaseGenerated extends AbstractIrTextTestCase {
|
|||||||
doTest(fileName);
|
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")
|
@TestMetadata("badBreakContinue.kt")
|
||||||
public void testBadBreakContinue() throws Exception {
|
public void testBadBreakContinue() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/expressions/badBreakContinue.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/expressions/badBreakContinue.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user