From f55ff8eb1b6375d382d4350d81f85738f453d054 Mon Sep 17 00:00:00 2001 From: Mark Punzalan Date: Thu, 17 Sep 2020 22:42:43 -0700 Subject: [PATCH] [FIR] Capture receiver for pre/postfix dec/increment of qualified access This prevents double-evaluation of the receiver expression, which may have side-effects. E.g.: a.b++ --- .../fir/lightTree/converter/BaseConverter.kt | 15 +- .../kotlin/fir/builder/RawFirBuilder.kt | 3 + .../testData/rawBuilder/expressions/unary.txt | 23 +-- .../kotlin/fir/builder/BaseFirBuilder.kt | 191 ++++++++++++++++-- .../codegen/box/jvmStatic/postfixInc.kt | 1 - .../codegen/box/jvmStatic/prefixInc.kt | 1 - .../codegen/box/lazyCodegen/increment.kt | 1 - .../breakContinueInLoopHeader.fir.txt | 8 +- .../expressions/breakContinueInWhen.fir.txt | 4 +- .../complexAugmentedAssignment.fir.txt | 46 +++-- .../expressions/incrementDecrement.fir.txt | 78 +++---- ...javaSyntheticGenericPropertyAccess.fir.txt | 12 +- .../javaSyntheticPropertyAccess.fir.txt | 12 +- 13 files changed, 278 insertions(+), 117 deletions(-) diff --git a/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/BaseConverter.kt b/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/BaseConverter.kt index aeb2b7d1139..73f829ade1b 100644 --- a/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/BaseConverter.kt +++ b/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/BaseConverter.kt @@ -7,6 +7,7 @@ package org.jetbrains.kotlin.fir.lightTree.converter import com.intellij.lang.LighterASTNode import com.intellij.openapi.util.Ref +import com.intellij.psi.TokenType import com.intellij.psi.tree.IElementType import com.intellij.util.diff.FlyweightCapableTreeStructure import org.jetbrains.kotlin.KtNodeTypes @@ -81,13 +82,25 @@ open class BaseConverter( return this.getChildNodesByType(type).firstOrNull() } + override val LighterASTNode?.receiverExpression: LighterASTNode? + get() { + var candidate: LighterASTNode? = null + this?.forEachChildren { + when (it.tokenType) { + DOT, SAFE_ACCESS -> return if (candidate?.elementType != TokenType.ERROR_ELEMENT) candidate else null + else -> candidate = it + } + } + return null + } + override val LighterASTNode?.selectorExpression: LighterASTNode? get() { var isSelector = false this?.forEachChildren { when (it.tokenType) { DOT, SAFE_ACCESS -> isSelector = true - else -> if (isSelector) return it + else -> if (isSelector) return if (it.elementType != TokenType.ERROR_ELEMENT) it else null } } return null diff --git a/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt b/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt index ba4f67f1d59..5d08b6d9626 100644 --- a/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt +++ b/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt @@ -122,6 +122,9 @@ class RawFirBuilder( return (this as KtAnnotatedExpression).baseExpression } + override val PsiElement?.receiverExpression: PsiElement? + get() = (this as? KtQualifiedExpression)?.receiverExpression + override val PsiElement?.selectorExpression: PsiElement? get() = (this as? KtQualifiedExpression)?.selectorExpression diff --git a/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/unary.txt b/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/unary.txt index e9f84a112d0..cf28bd644b4 100644 --- a/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/unary.txt +++ b/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/unary.txt @@ -8,14 +8,12 @@ FILE: unary.kt } lval x2: = { - lval : = x# - x# = R|/|.inc#() + x# = x#.inc#() x# } lval x3: = { - lval : = x# - x# = R|/|.dec#() + x# = x#.dec#() x# } @@ -43,15 +41,16 @@ FILE: unary.kt } public? final? fun test2(x: X): R|kotlin/Unit| { lval x1: = { - lval : = x#.i# - x#.i# = R|/|.inc#() + lval : = x# + lval : = R|/|.i# + R|/|.i# = R|/|.inc#() R|/| } lval x2: = { - lval : = x#.i# - lval : = R|/|.inc#() - x#.i# = R|/| + lval : = x# + lval : = R|/|.i#.inc#() + R|/|.i# = R|/| R|/| } @@ -64,8 +63,7 @@ FILE: unary.kt } lval x2: = { - lval : = arr#.get#(IntegerLiteral(1)) - lval : = R|/|.inc#() + lval : = arr#.get#(IntegerLiteral(1)).inc#() arr#.set#(IntegerLiteral(1), R|/|) R|/| } @@ -88,8 +86,7 @@ FILE: unary.kt } lval x2: = { - lval : = y#.arr#.get#(IntegerLiteral(1)) - lval : = R|/|.inc#() + lval : = y#.arr#.get#(IntegerLiteral(1)).inc#() y#.arr#.set#(IntegerLiteral(1), R|/|) R|/| } diff --git a/compiler/fir/raw-fir/raw-fir.common/src/org/jetbrains/kotlin/fir/builder/BaseFirBuilder.kt b/compiler/fir/raw-fir/raw-fir.common/src/org/jetbrains/kotlin/fir/builder/BaseFirBuilder.kt index e7be2cd21c2..917320ed62f 100644 --- a/compiler/fir/raw-fir/raw-fir.common/src/org/jetbrains/kotlin/fir/builder/BaseFirBuilder.kt +++ b/compiler/fir/raw-fir/raw-fir.common/src/org/jetbrains/kotlin/fir/builder/BaseFirBuilder.kt @@ -19,10 +19,12 @@ import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.expressions.builder.* import org.jetbrains.kotlin.fir.references.FirReference import org.jetbrains.kotlin.fir.references.builder.* +import org.jetbrains.kotlin.fir.references.impl.FirSimpleNamedReference import org.jetbrains.kotlin.fir.symbols.CallableId import org.jetbrains.kotlin.fir.symbols.impl.* -import org.jetbrains.kotlin.fir.types.* -import org.jetbrains.kotlin.fir.types.builder.* +import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef +import org.jetbrains.kotlin.fir.types.FirTypeRef +import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl import org.jetbrains.kotlin.lexer.KtTokens.CLOSING_QUOTE @@ -50,6 +52,7 @@ abstract class BaseFirBuilder(val baseSession: FirSession, val context: Conte abstract fun T.getExpressionInParentheses(): T? abstract fun T.getAnnotatedExpression(): T? abstract fun T.getChildNodeByType(type: IElementType): T? + abstract val T?.receiverExpression: T? abstract val T?.selectorExpression: T? /**** Class name utils ****/ @@ -383,14 +386,17 @@ abstract class BaseFirBuilder(val baseSession: FirSession, val context: Conte * * result: * { - * val = argument - * argument = .inc() - * ^argument + * val = argument.inc() + * argument = + * ^ * } * */ - // TODO: Refactor, support receiver capturing in case of a.b + // TODO: + // 1. Support receiver capturing for `array.b++` (elementType == ARRAY_ACCESS_EXPRESSION). + // 2. Support receiver capturing for `a?.b++` (elementType == SAFE_ACCESS_EXPRESSION). + // 3. Add box test cases for #1 and #2 where receiver expression has side effects. fun generateIncrementOrDecrementBlock( baseExpression: T, operationReference: T?, @@ -405,31 +411,67 @@ abstract class BaseFirBuilder(val baseSession: FirSession, val context: Conte diagnostic = ConeSimpleDiagnostic("Inc/dec without operand", DiagnosticKind.Syntax) } } + + if (argument.elementType == PARENTHESIZED) { + return generateIncrementOrDecrementBlock( + baseExpression, + operationReference, + argument.getExpressionInParentheses(), + callName, + prefix, + convert + ) + } + + if (argument.elementType == DOT_QUALIFIED_EXPRESSION) { + return generateIncrementOrDecrementBlockForQualifiedAccess( + baseExpression, + operationReference, + argument, + callName, + prefix, + convert + ) + } + return buildBlock { val baseSource = baseExpression?.toFirSourceElement() val desugaredSource = baseSource?.fakeElement(FirFakeSourceElementKind.DesugaredIncrementOrDecrement) source = desugaredSource - val tempName = Name.special("") - val temporaryVariable = generateTemporaryVariable( + + // initialValueVar is only used for postfix increment/decrement (stores the argument value before increment/decrement). + val initialValueVar = generateTemporaryVariable( this@BaseFirBuilder.baseSession, desugaredSource, - tempName, + Name.special(""), argument.convert() ) - statements += temporaryVariable - val resultName = Name.special("") + + // resultInitializer is the expression for `argument.inc()` val resultInitializer = buildFunctionCall { source = desugaredSource calleeReference = buildSimpleNamedReference { source = operationReference?.toFirSourceElement() name = callName } - explicitReceiver = generateResolvedAccessExpression(desugaredSource, temporaryVariable) + explicitReceiver = if (prefix) { + argument.convert() + } else { + generateResolvedAccessExpression(desugaredSource, initialValueVar) + } } - val resultVar = generateTemporaryVariable(this@BaseFirBuilder.baseSession, desugaredSource, resultName, resultInitializer) + + // resultVar is only used for prefix increment/decrement. + val resultVar = generateTemporaryVariable( + this@BaseFirBuilder.baseSession, + desugaredSource, + Name.special(""), + resultInitializer + ) + val assignment = argument.generateAssignment( desugaredSource, - argument, + null, if (prefix && argument.elementType != REFERENCE_EXPRESSION) generateResolvedAccessExpression(source, resultVar) else @@ -455,8 +497,127 @@ abstract class BaseFirBuilder(val baseSession: FirSession, val context: Conte statements += generateAccessExpression(desugaredSource, argument.getReferencedNameAsName()) } } else { + statements += initialValueVar appendAssignment() - statements += generateResolvedAccessExpression(desugaredSource, temporaryVariable) + statements += generateResolvedAccessExpression(desugaredSource, initialValueVar) + } + } + } + + /** + * given: + * a.b++ + * + * result: + * { + * val = a + * val = .b + * .b = .inc() + * ^ + * } + * + * given: + * ++a.b + * + * result: + * { + * val = a + * val = .b.inc() + * .b = + * ^ + * } + * + */ + private fun generateIncrementOrDecrementBlockForQualifiedAccess( + baseExpression: T, + operationReference: T?, + argument: T, + callName: Name, + prefix: Boolean, + convert: T.() -> FirExpression + ): FirExpression { + return buildBlock { + val baseSource = baseExpression?.toFirSourceElement() + val desugaredSource = baseSource?.fakeElement(FirFakeSourceElementKind.DesugaredIncrementOrDecrement) + source = desugaredSource + + val argumentReceiver = argument.receiverExpression + val argumentSelector = argument.selectorExpression + + val argumentReceiverVariable = generateTemporaryVariable( + this@BaseFirBuilder.baseSession, + argumentReceiver?.toFirSourceElement(), + Name.special(""), + argumentReceiver?.convert() ?: buildErrorExpression { + source = argument.toFirSourceElement() + diagnostic = ConeSimpleDiagnostic("Qualified expression without receiver", DiagnosticKind.Syntax) + } + ).also { statements += it } + + val firArgument = generateResolvedAccessExpression(argumentReceiverVariable.source, argumentReceiverVariable).let { receiver -> + val firArgumentSelector = argumentSelector?.convert() ?: buildErrorExpression { + source = argument.toFirSourceElement() + diagnostic = ConeSimpleDiagnostic("Qualified expression without selector", DiagnosticKind.Syntax) + } + firArgumentSelector.also { if (it is FirQualifiedAccessExpression) it.replaceExplicitReceiver(receiver) } + } + + // initialValueVar is only used for postfix increment/decrement (stores the argument value before increment/decrement). + val initialValueVar = generateTemporaryVariable( + this@BaseFirBuilder.baseSession, + desugaredSource, + Name.special(""), + firArgument + ) + + // resultInitializer is the expression for `argument.inc()` + val resultInitializer = buildFunctionCall { + source = desugaredSource + calleeReference = buildSimpleNamedReference { + source = operationReference?.toFirSourceElement() + name = callName + } + explicitReceiver = if (prefix) { + firArgument + } else { + generateResolvedAccessExpression(desugaredSource, initialValueVar) + } + } + + // resultVar is only used for prefix increment/decrement. + val resultVar = generateTemporaryVariable( + this@BaseFirBuilder.baseSession, + desugaredSource, + Name.special(""), + resultInitializer + ) + + fun appendAssignment() { + if (firArgument is FirQualifiedAccessExpression) { + statements += buildVariableAssignment { + source = desugaredSource + rValue = if (prefix) { + generateResolvedAccessExpression(source, resultVar) + } else { + resultInitializer + } + explicitReceiver = generateResolvedAccessExpression(argumentReceiverVariable.source, argumentReceiverVariable) + calleeReference = buildSimpleNamedReference { + source = firArgument.calleeReference.source + name = (firArgument.calleeReference as FirSimpleNamedReference).name + } + } + } + } + + if (prefix) { + statements += resultVar + appendAssignment() + statements += generateResolvedAccessExpression(desugaredSource, resultVar) + } else { + statements += initialValueVar + appendAssignment() + statements += generateResolvedAccessExpression(desugaredSource, initialValueVar) } } } diff --git a/compiler/testData/codegen/box/jvmStatic/postfixInc.kt b/compiler/testData/codegen/box/jvmStatic/postfixInc.kt index 092ac524934..03989995324 100644 --- a/compiler/testData/codegen/box/jvmStatic/postfixInc.kt +++ b/compiler/testData/codegen/box/jvmStatic/postfixInc.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR // TARGET_BACKEND: JVM // WITH_RUNTIME diff --git a/compiler/testData/codegen/box/jvmStatic/prefixInc.kt b/compiler/testData/codegen/box/jvmStatic/prefixInc.kt index 60e787f7f2f..7177f224d85 100644 --- a/compiler/testData/codegen/box/jvmStatic/prefixInc.kt +++ b/compiler/testData/codegen/box/jvmStatic/prefixInc.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR // TARGET_BACKEND: JVM // WITH_RUNTIME diff --git a/compiler/testData/codegen/box/lazyCodegen/increment.kt b/compiler/testData/codegen/box/lazyCodegen/increment.kt index 1ac7e86e2fb..40369fff4af 100644 --- a/compiler/testData/codegen/box/lazyCodegen/increment.kt +++ b/compiler/testData/codegen/box/lazyCodegen/increment.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR var holder = "" var globalA: A = A(-1) get(): A { diff --git a/compiler/testData/ir/irText/expressions/breakContinueInLoopHeader.fir.txt b/compiler/testData/ir/irText/expressions/breakContinueInLoopHeader.fir.txt index 719ae858383..89f3809e6e0 100644 --- a/compiler/testData/ir/irText/expressions/breakContinueInLoopHeader.fir.txt +++ b/compiler/testData/ir/irText/expressions/breakContinueInLoopHeader.fir.txt @@ -106,22 +106,18 @@ FILE fqName: fileName:/breakContinueInLoopHeader.kt WHILE label=Outer origin=WHILE_LOOP condition: CONST Boolean type=kotlin.Boolean value=true body: BLOCK type=kotlin.Unit origin=WHILE_LOOP - VAR IR_TEMPORARY_VARIABLE name:tmp_6 type:kotlin.Int [val] - GET_VAR 'var i: kotlin.Int [var] declared in .test5' type=kotlin.Int origin=null SET_VAR 'var i: kotlin.Int [var] declared in .test5' type=kotlin.Unit origin=EQ CALL 'public final fun inc (): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null - $this: GET_VAR 'val tmp_6: kotlin.Int [val] declared in .test5' type=kotlin.Int origin=null + $this: GET_VAR 'var i: kotlin.Int [var] declared in .test5' type=kotlin.Int origin=null TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit GET_VAR 'var i: kotlin.Int [var] declared in .test5' type=kotlin.Int origin=null VAR name:j type:kotlin.Int [var] CONST Int type=kotlin.Int value=0 DO_WHILE label=Inner origin=DO_WHILE_LOOP body: COMPOSITE type=kotlin.Int origin=DO_WHILE_LOOP - VAR IR_TEMPORARY_VARIABLE name:tmp_7 type:kotlin.Int [val] - GET_VAR 'var j: kotlin.Int [var] declared in .test5' type=kotlin.Int origin=null SET_VAR 'var j: kotlin.Int [var] declared in .test5' type=kotlin.Unit origin=EQ CALL 'public final fun inc (): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null - $this: GET_VAR 'val tmp_7: kotlin.Int [val] declared in .test5' type=kotlin.Int origin=null + $this: GET_VAR 'var j: kotlin.Int [var] declared in .test5' type=kotlin.Int origin=null GET_VAR 'var j: kotlin.Int [var] declared in .test5' type=kotlin.Int origin=null condition: WHEN type=kotlin.Boolean origin=IF BRANCH diff --git a/compiler/testData/ir/irText/expressions/breakContinueInWhen.fir.txt b/compiler/testData/ir/irText/expressions/breakContinueInWhen.fir.txt index 98d4f3320de..fa2946013ce 100644 --- a/compiler/testData/ir/irText/expressions/breakContinueInWhen.fir.txt +++ b/compiler/testData/ir/irText/expressions/breakContinueInWhen.fir.txt @@ -109,11 +109,9 @@ FILE fqName: fileName:/breakContinueInWhen.kt CONST String type=kotlin.String value="" DO_WHILE label=null origin=DO_WHILE_LOOP body: COMPOSITE type=kotlin.Unit origin=DO_WHILE_LOOP - VAR IR_TEMPORARY_VARIABLE name:tmp_2 type:kotlin.Int [val] - GET_VAR 'var k: kotlin.Int [var] declared in .testContinueDoWhile' type=kotlin.Int origin=null SET_VAR 'var k: kotlin.Int [var] declared in .testContinueDoWhile' type=kotlin.Unit origin=EQ CALL 'public final fun inc (): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null - $this: GET_VAR 'val tmp_2: kotlin.Int [val] declared in .testContinueDoWhile' type=kotlin.Int origin=null + $this: GET_VAR 'var k: kotlin.Int [var] declared in .testContinueDoWhile' type=kotlin.Int origin=null TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit GET_VAR 'var k: kotlin.Int [var] declared in .testContinueDoWhile' type=kotlin.Int origin=null WHEN type=kotlin.Unit origin=WHEN diff --git a/compiler/testData/ir/irText/expressions/complexAugmentedAssignment.fir.txt b/compiler/testData/ir/irText/expressions/complexAugmentedAssignment.fir.txt index 88cd4498583..10cf9fa2ca4 100644 --- a/compiler/testData/ir/irText/expressions/complexAugmentedAssignment.fir.txt +++ b/compiler/testData/ir/irText/expressions/complexAugmentedAssignment.fir.txt @@ -143,33 +143,39 @@ FILE fqName: fileName:/complexAugmentedAssignment.kt GET_VAR 'val tmp_0: kotlin.Int [val] declared in .test1' type=kotlin.Int origin=null FUN name:test2 visibility:public modality:FINAL <> () returnType:kotlin.Unit BLOCK_BODY - VAR IR_TEMPORARY_VARIABLE name:tmp_3 type:kotlin.Int [val] - CALL 'public final fun (): kotlin.Int declared in .X1' type=kotlin.Int origin=GET_PROPERTY - $this: GET_OBJECT 'CLASS OBJECT name:X1 modality:FINAL visibility:public superTypes:[kotlin.Any]' type=.X1 - CALL 'public final fun (: kotlin.Int): kotlin.Unit declared in .X1' type=kotlin.Unit origin=EQ - $this: GET_OBJECT 'CLASS OBJECT name:X1 modality:FINAL visibility:public superTypes:[kotlin.Any]' type=.X1 - : CALL 'public final fun inc (): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null - $this: GET_VAR 'val tmp_3: kotlin.Int [val] declared in .test2' type=kotlin.Int origin=null - TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit - GET_VAR 'val tmp_3: kotlin.Int [val] declared in .test2' type=kotlin.Int origin=null + VAR IR_TEMPORARY_VARIABLE name:tmp_3 type:.X1 [val] + GET_OBJECT 'CLASS OBJECT name:X1 modality:FINAL visibility:public superTypes:[kotlin.Any]' type=.X1 VAR IR_TEMPORARY_VARIABLE name:tmp_4 type:kotlin.Int [val] - CALL 'public final fun (): kotlin.Int declared in .X1.X2' type=kotlin.Int origin=GET_PROPERTY - $this: GET_OBJECT 'CLASS OBJECT name:X2 modality:FINAL visibility:public superTypes:[kotlin.Any]' type=.X1.X2 - CALL 'public final fun (: kotlin.Int): kotlin.Unit declared in .X1.X2' type=kotlin.Unit origin=EQ - $this: GET_OBJECT 'CLASS OBJECT name:X2 modality:FINAL visibility:public superTypes:[kotlin.Any]' type=.X1.X2 + CALL 'public final fun (): kotlin.Int declared in .X1' type=kotlin.Int origin=GET_PROPERTY + $this: GET_VAR 'val tmp_3: .X1 [val] declared in .test2' type=.X1 origin=null + CALL 'public final fun (: kotlin.Int): kotlin.Unit declared in .X1' type=kotlin.Unit origin=EQ + $this: GET_VAR 'val tmp_3: .X1 [val] declared in .test2' type=.X1 origin=null : CALL 'public final fun inc (): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null $this: GET_VAR 'val tmp_4: kotlin.Int [val] declared in .test2' type=kotlin.Int origin=null TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit GET_VAR 'val tmp_4: kotlin.Int [val] declared in .test2' type=kotlin.Int origin=null - VAR IR_TEMPORARY_VARIABLE name:tmp_5 type:kotlin.Int [val] - CALL 'public final fun (): kotlin.Int declared in .X1.X2.X3' type=kotlin.Int origin=GET_PROPERTY - $this: GET_OBJECT 'CLASS OBJECT name:X3 modality:FINAL visibility:public superTypes:[kotlin.Any]' type=.X1.X2.X3 - CALL 'public final fun (: kotlin.Int): kotlin.Unit declared in .X1.X2.X3' type=kotlin.Unit origin=EQ - $this: GET_OBJECT 'CLASS OBJECT name:X3 modality:FINAL visibility:public superTypes:[kotlin.Any]' type=.X1.X2.X3 + VAR IR_TEMPORARY_VARIABLE name:tmp_5 type:.X1.X2 [val] + GET_OBJECT 'CLASS OBJECT name:X2 modality:FINAL visibility:public superTypes:[kotlin.Any]' type=.X1.X2 + VAR IR_TEMPORARY_VARIABLE name:tmp_6 type:kotlin.Int [val] + CALL 'public final fun (): kotlin.Int declared in .X1.X2' type=kotlin.Int origin=GET_PROPERTY + $this: GET_VAR 'val tmp_5: .X1.X2 [val] declared in .test2' type=.X1.X2 origin=null + CALL 'public final fun (: kotlin.Int): kotlin.Unit declared in .X1.X2' type=kotlin.Unit origin=EQ + $this: GET_VAR 'val tmp_5: .X1.X2 [val] declared in .test2' type=.X1.X2 origin=null : CALL 'public final fun inc (): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null - $this: GET_VAR 'val tmp_5: kotlin.Int [val] declared in .test2' type=kotlin.Int origin=null + $this: GET_VAR 'val tmp_6: kotlin.Int [val] declared in .test2' type=kotlin.Int origin=null TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit - GET_VAR 'val tmp_5: kotlin.Int [val] declared in .test2' type=kotlin.Int origin=null + GET_VAR 'val tmp_6: kotlin.Int [val] declared in .test2' type=kotlin.Int origin=null + VAR IR_TEMPORARY_VARIABLE name:tmp_7 type:.X1.X2.X3 [val] + GET_OBJECT 'CLASS OBJECT name:X3 modality:FINAL visibility:public superTypes:[kotlin.Any]' type=.X1.X2.X3 + VAR IR_TEMPORARY_VARIABLE name:tmp_8 type:kotlin.Int [val] + CALL 'public final fun (): kotlin.Int declared in .X1.X2.X3' type=kotlin.Int origin=GET_PROPERTY + $this: GET_VAR 'val tmp_7: .X1.X2.X3 [val] declared in .test2' type=.X1.X2.X3 origin=null + CALL 'public final fun (: kotlin.Int): kotlin.Unit declared in .X1.X2.X3' type=kotlin.Unit origin=EQ + $this: GET_VAR 'val tmp_7: .X1.X2.X3 [val] declared in .test2' type=.X1.X2.X3 origin=null + : CALL 'public final fun inc (): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null + $this: GET_VAR 'val tmp_8: kotlin.Int [val] declared in .test2' type=kotlin.Int origin=null + TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit + GET_VAR 'val tmp_8: kotlin.Int [val] declared in .test2' type=kotlin.Int origin=null CLASS CLASS name:B modality:FINAL visibility:public superTypes:[kotlin.Any] $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.B CONSTRUCTOR visibility:public <> (s:kotlin.Int) returnType:.B [primary] diff --git a/compiler/testData/ir/irText/expressions/incrementDecrement.fir.txt b/compiler/testData/ir/irText/expressions/incrementDecrement.fir.txt index cb8e881dcf9..4a1b091522b 100644 --- a/compiler/testData/ir/irText/expressions/incrementDecrement.fir.txt +++ b/compiler/testData/ir/irText/expressions/incrementDecrement.fir.txt @@ -33,19 +33,15 @@ FILE fqName: fileName:/incrementDecrement.kt CONST Int type=kotlin.Int value=0 VAR name:x1 type:kotlin.Int [val] BLOCK type=kotlin.Int origin=null - VAR IR_TEMPORARY_VARIABLE name:tmp_0 type:kotlin.Int [val] - GET_VAR 'var x: kotlin.Int [var] declared in .testVarPrefix' type=kotlin.Int origin=null SET_VAR 'var x: kotlin.Int [var] declared in .testVarPrefix' type=kotlin.Unit origin=EQ CALL 'public final fun inc (): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null - $this: GET_VAR 'val tmp_0: kotlin.Int [val] declared in .testVarPrefix' type=kotlin.Int origin=null + $this: GET_VAR 'var x: kotlin.Int [var] declared in .testVarPrefix' type=kotlin.Int origin=null GET_VAR 'var x: kotlin.Int [var] declared in .testVarPrefix' type=kotlin.Int origin=null VAR name:x2 type:kotlin.Int [val] BLOCK type=kotlin.Int origin=null - VAR IR_TEMPORARY_VARIABLE name:tmp_1 type:kotlin.Int [val] - GET_VAR 'var x: kotlin.Int [var] declared in .testVarPrefix' type=kotlin.Int origin=null SET_VAR 'var x: kotlin.Int [var] declared in .testVarPrefix' type=kotlin.Unit origin=EQ CALL 'public final fun dec (): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null - $this: GET_VAR 'val tmp_1: kotlin.Int [val] declared in .testVarPrefix' type=kotlin.Int origin=null + $this: GET_VAR 'var x: kotlin.Int [var] declared in .testVarPrefix' type=kotlin.Int origin=null GET_VAR 'var x: kotlin.Int [var] declared in .testVarPrefix' type=kotlin.Int origin=null FUN name:testVarPostfix visibility:public modality:FINAL <> () returnType:kotlin.Unit BLOCK_BODY @@ -53,91 +49,81 @@ FILE fqName: fileName:/incrementDecrement.kt CONST Int type=kotlin.Int value=0 VAR name:x1 type:kotlin.Int [val] BLOCK type=kotlin.Int origin=null - VAR IR_TEMPORARY_VARIABLE name:tmp_2 type:kotlin.Int [val] + VAR IR_TEMPORARY_VARIABLE name:tmp_0 type:kotlin.Int [val] GET_VAR 'var x: kotlin.Int [var] declared in .testVarPostfix' type=kotlin.Int origin=null SET_VAR 'var x: kotlin.Int [var] declared in .testVarPostfix' type=kotlin.Unit origin=EQ CALL 'public final fun inc (): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null - $this: GET_VAR 'val tmp_2: kotlin.Int [val] declared in .testVarPostfix' type=kotlin.Int origin=null - GET_VAR 'val tmp_2: kotlin.Int [val] declared in .testVarPostfix' type=kotlin.Int origin=null + $this: GET_VAR 'val tmp_0: kotlin.Int [val] declared in .testVarPostfix' type=kotlin.Int origin=null + GET_VAR 'val tmp_0: kotlin.Int [val] declared in .testVarPostfix' type=kotlin.Int origin=null VAR name:x2 type:kotlin.Int [val] BLOCK type=kotlin.Int origin=null - VAR IR_TEMPORARY_VARIABLE name:tmp_3 type:kotlin.Int [val] + VAR IR_TEMPORARY_VARIABLE name:tmp_1 type:kotlin.Int [val] GET_VAR 'var x: kotlin.Int [var] declared in .testVarPostfix' type=kotlin.Int origin=null SET_VAR 'var x: kotlin.Int [var] declared in .testVarPostfix' type=kotlin.Unit origin=EQ CALL 'public final fun dec (): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null - $this: GET_VAR 'val tmp_3: kotlin.Int [val] declared in .testVarPostfix' type=kotlin.Int origin=null - GET_VAR 'val tmp_3: kotlin.Int [val] declared in .testVarPostfix' type=kotlin.Int origin=null + $this: GET_VAR 'val tmp_1: kotlin.Int [val] declared in .testVarPostfix' type=kotlin.Int origin=null + GET_VAR 'val tmp_1: kotlin.Int [val] declared in .testVarPostfix' type=kotlin.Int origin=null FUN name:testPropPrefix visibility:public modality:FINAL <> () returnType:kotlin.Unit BLOCK_BODY VAR name:p1 type:kotlin.Int [val] BLOCK type=kotlin.Int origin=null - VAR IR_TEMPORARY_VARIABLE name:tmp_4 type:kotlin.Int [val] - CALL 'public final fun (): kotlin.Int declared in ' type=kotlin.Int origin=GET_PROPERTY CALL 'public final fun (: kotlin.Int): kotlin.Unit declared in ' type=kotlin.Unit origin=EQ : CALL 'public final fun inc (): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null - $this: GET_VAR 'val tmp_4: kotlin.Int [val] declared in .testPropPrefix' type=kotlin.Int origin=null + $this: CALL 'public final fun (): kotlin.Int declared in ' type=kotlin.Int origin=GET_PROPERTY CALL 'public final fun (): kotlin.Int declared in ' type=kotlin.Int origin=GET_PROPERTY VAR name:p2 type:kotlin.Int [val] BLOCK type=kotlin.Int origin=null - VAR IR_TEMPORARY_VARIABLE name:tmp_5 type:kotlin.Int [val] - CALL 'public final fun (): kotlin.Int declared in ' type=kotlin.Int origin=GET_PROPERTY CALL 'public final fun (: kotlin.Int): kotlin.Unit declared in ' type=kotlin.Unit origin=EQ : CALL 'public final fun dec (): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null - $this: GET_VAR 'val tmp_5: kotlin.Int [val] declared in .testPropPrefix' type=kotlin.Int origin=null + $this: CALL 'public final fun (): kotlin.Int declared in ' type=kotlin.Int origin=GET_PROPERTY CALL 'public final fun (): kotlin.Int declared in ' type=kotlin.Int origin=GET_PROPERTY FUN name:testPropPostfix visibility:public modality:FINAL <> () returnType:kotlin.Unit BLOCK_BODY VAR name:p1 type:kotlin.Int [val] BLOCK type=kotlin.Int origin=null - VAR IR_TEMPORARY_VARIABLE name:tmp_6 type:kotlin.Int [val] + VAR IR_TEMPORARY_VARIABLE name:tmp_2 type:kotlin.Int [val] CALL 'public final fun (): kotlin.Int declared in ' type=kotlin.Int origin=GET_PROPERTY CALL 'public final fun (: kotlin.Int): kotlin.Unit declared in ' type=kotlin.Unit origin=EQ : CALL 'public final fun inc (): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null - $this: GET_VAR 'val tmp_6: kotlin.Int [val] declared in .testPropPostfix' type=kotlin.Int origin=null - GET_VAR 'val tmp_6: kotlin.Int [val] declared in .testPropPostfix' type=kotlin.Int origin=null + $this: GET_VAR 'val tmp_2: kotlin.Int [val] declared in .testPropPostfix' type=kotlin.Int origin=null + GET_VAR 'val tmp_2: kotlin.Int [val] declared in .testPropPostfix' type=kotlin.Int origin=null VAR name:p2 type:kotlin.Int [val] BLOCK type=kotlin.Int origin=null - VAR IR_TEMPORARY_VARIABLE name:tmp_7 type:kotlin.Int [val] - CALL 'public final fun (): kotlin.Int declared in ' type=kotlin.Int origin=GET_PROPERTY CALL 'public final fun (: kotlin.Int): kotlin.Unit declared in ' type=kotlin.Unit origin=EQ : CALL 'public final fun dec (): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null - $this: GET_VAR 'val tmp_7: kotlin.Int [val] declared in .testPropPostfix' type=kotlin.Int origin=null + $this: CALL 'public final fun (): kotlin.Int declared in ' type=kotlin.Int origin=GET_PROPERTY CALL 'public final fun (): kotlin.Int declared in ' type=kotlin.Int origin=GET_PROPERTY FUN name:testArrayPrefix visibility:public modality:FINAL <> () returnType:kotlin.Unit BLOCK_BODY VAR name:a1 type:kotlin.Int [val] BLOCK type=kotlin.Int origin=null - VAR IR_TEMPORARY_VARIABLE name:tmp_8 type:kotlin.Int [val] - CALL 'public final fun get (index: kotlin.Int): kotlin.Int [operator] declared in kotlin.IntArray' type=kotlin.Int origin=null - $this: CALL 'public final fun (): kotlin.IntArray declared in ' type=kotlin.IntArray origin=GET_PROPERTY - index: CONST Int type=kotlin.Int value=0 - VAR IR_TEMPORARY_VARIABLE name:tmp_9 type:kotlin.Int [val] + VAR IR_TEMPORARY_VARIABLE name:tmp_3 type:kotlin.Int [val] CALL 'public final fun inc (): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null - $this: GET_VAR 'val tmp_8: kotlin.Int [val] declared in .testArrayPrefix' type=kotlin.Int origin=null + $this: CALL 'public final fun get (index: kotlin.Int): kotlin.Int [operator] declared in kotlin.IntArray' type=kotlin.Int origin=null + $this: CALL 'public final fun (): kotlin.IntArray declared in ' type=kotlin.IntArray origin=GET_PROPERTY + index: CONST Int type=kotlin.Int value=0 CALL 'public final fun set (index: kotlin.Int, value: kotlin.Int): kotlin.Unit [operator] declared in kotlin.IntArray' type=kotlin.Unit origin=null $this: CALL 'public final fun (): kotlin.IntArray declared in ' type=kotlin.IntArray origin=GET_PROPERTY index: CONST Int type=kotlin.Int value=0 - value: GET_VAR 'val tmp_9: kotlin.Int [val] declared in .testArrayPrefix' type=kotlin.Int origin=null - GET_VAR 'val tmp_9: kotlin.Int [val] declared in .testArrayPrefix' type=kotlin.Int origin=null + value: GET_VAR 'val tmp_3: kotlin.Int [val] declared in .testArrayPrefix' type=kotlin.Int origin=null + GET_VAR 'val tmp_3: kotlin.Int [val] declared in .testArrayPrefix' type=kotlin.Int origin=null VAR name:a2 type:kotlin.Int [val] BLOCK type=kotlin.Int origin=null - VAR IR_TEMPORARY_VARIABLE name:tmp_10 type:kotlin.Int [val] - CALL 'public final fun get (index: kotlin.Int): kotlin.Int [operator] declared in kotlin.IntArray' type=kotlin.Int origin=null - $this: CALL 'public final fun (): kotlin.IntArray declared in ' type=kotlin.IntArray origin=GET_PROPERTY - index: CONST Int type=kotlin.Int value=0 - VAR IR_TEMPORARY_VARIABLE name:tmp_11 type:kotlin.Int [val] + VAR IR_TEMPORARY_VARIABLE name:tmp_4 type:kotlin.Int [val] CALL 'public final fun dec (): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null - $this: GET_VAR 'val tmp_10: kotlin.Int [val] declared in .testArrayPrefix' type=kotlin.Int origin=null + $this: CALL 'public final fun get (index: kotlin.Int): kotlin.Int [operator] declared in kotlin.IntArray' type=kotlin.Int origin=null + $this: CALL 'public final fun (): kotlin.IntArray declared in ' type=kotlin.IntArray origin=GET_PROPERTY + index: CONST Int type=kotlin.Int value=0 CALL 'public final fun set (index: kotlin.Int, value: kotlin.Int): kotlin.Unit [operator] declared in kotlin.IntArray' type=kotlin.Unit origin=null $this: CALL 'public final fun (): kotlin.IntArray declared in ' type=kotlin.IntArray origin=GET_PROPERTY index: CONST Int type=kotlin.Int value=0 - value: GET_VAR 'val tmp_11: kotlin.Int [val] declared in .testArrayPrefix' type=kotlin.Int origin=null - GET_VAR 'val tmp_11: kotlin.Int [val] declared in .testArrayPrefix' type=kotlin.Int origin=null + value: GET_VAR 'val tmp_4: kotlin.Int [val] declared in .testArrayPrefix' type=kotlin.Int origin=null + GET_VAR 'val tmp_4: kotlin.Int [val] declared in .testArrayPrefix' type=kotlin.Int origin=null FUN name:testArrayPostfix visibility:public modality:FINAL <> () returnType:kotlin.Unit BLOCK_BODY VAR name:a1 type:kotlin.Int [val] BLOCK type=kotlin.Int origin=null - VAR IR_TEMPORARY_VARIABLE name:tmp_12 type:kotlin.Int [val] + VAR IR_TEMPORARY_VARIABLE name:tmp_5 type:kotlin.Int [val] CALL 'public final fun get (index: kotlin.Int): kotlin.Int [operator] declared in kotlin.IntArray' type=kotlin.Int origin=null $this: CALL 'public final fun (): kotlin.IntArray declared in ' type=kotlin.IntArray origin=GET_PROPERTY index: CONST Int type=kotlin.Int value=0 @@ -145,11 +131,11 @@ FILE fqName: fileName:/incrementDecrement.kt $this: CALL 'public final fun (): kotlin.IntArray declared in ' type=kotlin.IntArray origin=GET_PROPERTY index: CONST Int type=kotlin.Int value=0 value: CALL 'public final fun inc (): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null - $this: GET_VAR 'val tmp_12: kotlin.Int [val] declared in .testArrayPostfix' type=kotlin.Int origin=null - GET_VAR 'val tmp_12: kotlin.Int [val] declared in .testArrayPostfix' type=kotlin.Int origin=null + $this: GET_VAR 'val tmp_5: kotlin.Int [val] declared in .testArrayPostfix' type=kotlin.Int origin=null + GET_VAR 'val tmp_5: kotlin.Int [val] declared in .testArrayPostfix' type=kotlin.Int origin=null VAR name:a2 type:kotlin.Int [val] BLOCK type=kotlin.Int origin=null - VAR IR_TEMPORARY_VARIABLE name:tmp_13 type:kotlin.Int [val] + VAR IR_TEMPORARY_VARIABLE name:tmp_6 type:kotlin.Int [val] CALL 'public final fun get (index: kotlin.Int): kotlin.Int [operator] declared in kotlin.IntArray' type=kotlin.Int origin=null $this: CALL 'public final fun (): kotlin.IntArray declared in ' type=kotlin.IntArray origin=GET_PROPERTY index: CONST Int type=kotlin.Int value=0 @@ -157,5 +143,5 @@ FILE fqName: fileName:/incrementDecrement.kt $this: CALL 'public final fun (): kotlin.IntArray declared in ' type=kotlin.IntArray origin=GET_PROPERTY index: CONST Int type=kotlin.Int value=0 value: CALL 'public final fun dec (): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null - $this: GET_VAR 'val tmp_13: kotlin.Int [val] declared in .testArrayPostfix' type=kotlin.Int origin=null - GET_VAR 'val tmp_13: kotlin.Int [val] declared in .testArrayPostfix' type=kotlin.Int origin=null + $this: GET_VAR 'val tmp_6: kotlin.Int [val] declared in .testArrayPostfix' type=kotlin.Int origin=null + GET_VAR 'val tmp_6: kotlin.Int [val] declared in .testArrayPostfix' type=kotlin.Int origin=null diff --git a/compiler/testData/ir/irText/expressions/javaSyntheticGenericPropertyAccess.fir.txt b/compiler/testData/ir/irText/expressions/javaSyntheticGenericPropertyAccess.fir.txt index cb9db9ab879..5f62a27df4f 100644 --- a/compiler/testData/ir/irText/expressions/javaSyntheticGenericPropertyAccess.fir.txt +++ b/compiler/testData/ir/irText/expressions/javaSyntheticGenericPropertyAccess.fir.txt @@ -9,15 +9,17 @@ FILE fqName: fileName:/javaSyntheticGenericPropertyAccess.kt CALL 'public open fun setFoo (x: kotlin.Int): kotlin.Unit declared in .J' type=kotlin.Unit origin=EQ $this: GET_VAR 'j: .J.test> declared in .test' type=.J.test> origin=null x: CONST Int type=kotlin.Int value=1 - VAR IR_TEMPORARY_VARIABLE name:tmp_0 type:kotlin.Int [val] + VAR IR_TEMPORARY_VARIABLE name:tmp_0 type:.J.test> [val] + GET_VAR 'j: .J.test> declared in .test' type=.J.test> origin=null + VAR IR_TEMPORARY_VARIABLE name:tmp_1 type:kotlin.Int [val] CALL 'public open fun getFoo (): kotlin.Int declared in .J' type=kotlin.Int origin=GET_PROPERTY - $this: GET_VAR 'j: .J.test> declared in .test' type=.J.test> origin=null + $this: GET_VAR 'val tmp_0: .J.test> [val] declared in .test' type=.J.test> origin=null CALL 'public open fun setFoo (x: kotlin.Int): kotlin.Unit declared in .J' type=kotlin.Unit origin=EQ - $this: GET_VAR 'j: .J.test> declared in .test' type=.J.test> origin=null + $this: GET_VAR 'val tmp_0: .J.test> [val] declared in .test' type=.J.test> origin=null x: CALL 'public final fun inc (): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null - $this: GET_VAR 'val tmp_0: kotlin.Int [val] declared in .test' type=kotlin.Int origin=null + $this: GET_VAR 'val tmp_1: kotlin.Int [val] declared in .test' type=kotlin.Int origin=null TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit - GET_VAR 'val tmp_0: kotlin.Int [val] declared in .test' type=kotlin.Int origin=null + GET_VAR 'val tmp_1: kotlin.Int [val] declared in .test' type=kotlin.Int origin=null CALL 'public open fun setFoo (x: kotlin.Int): kotlin.Unit declared in .J' type=kotlin.Unit origin=EQ $this: GET_VAR 'j: .J.test> declared in .test' type=.J.test> origin=null x: CALL 'public final fun plus (other: kotlin.Int): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null diff --git a/compiler/testData/ir/irText/expressions/javaSyntheticPropertyAccess.fir.txt b/compiler/testData/ir/irText/expressions/javaSyntheticPropertyAccess.fir.txt index c74ce0c9409..23d97d53bd3 100644 --- a/compiler/testData/ir/irText/expressions/javaSyntheticPropertyAccess.fir.txt +++ b/compiler/testData/ir/irText/expressions/javaSyntheticPropertyAccess.fir.txt @@ -8,15 +8,17 @@ FILE fqName: fileName:/javaSyntheticPropertyAccess.kt CALL 'public open fun setFoo (x: kotlin.Int): kotlin.Unit declared in .J' type=kotlin.Unit origin=EQ $this: GET_VAR 'j: .J declared in .test' type=.J origin=null x: CONST Int type=kotlin.Int value=1 - VAR IR_TEMPORARY_VARIABLE name:tmp_0 type:kotlin.Int [val] + VAR IR_TEMPORARY_VARIABLE name:tmp_0 type:.J [val] + GET_VAR 'j: .J declared in .test' type=.J origin=null + VAR IR_TEMPORARY_VARIABLE name:tmp_1 type:kotlin.Int [val] CALL 'public open fun getFoo (): kotlin.Int declared in .J' type=kotlin.Int origin=GET_PROPERTY - $this: GET_VAR 'j: .J declared in .test' type=.J origin=null + $this: GET_VAR 'val tmp_0: .J [val] declared in .test' type=.J origin=null CALL 'public open fun setFoo (x: kotlin.Int): kotlin.Unit declared in .J' type=kotlin.Unit origin=EQ - $this: GET_VAR 'j: .J declared in .test' type=.J origin=null + $this: GET_VAR 'val tmp_0: .J [val] declared in .test' type=.J origin=null x: CALL 'public final fun inc (): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null - $this: GET_VAR 'val tmp_0: kotlin.Int [val] declared in .test' type=kotlin.Int origin=null + $this: GET_VAR 'val tmp_1: kotlin.Int [val] declared in .test' type=kotlin.Int origin=null TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit - GET_VAR 'val tmp_0: kotlin.Int [val] declared in .test' type=kotlin.Int origin=null + GET_VAR 'val tmp_1: kotlin.Int [val] declared in .test' type=kotlin.Int origin=null CALL 'public open fun setFoo (x: kotlin.Int): kotlin.Unit declared in .J' type=kotlin.Unit origin=EQ $this: GET_VAR 'j: .J declared in .test' type=.J origin=null x: CALL 'public final fun plus (other: kotlin.Int): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null