[FIR] Support assignment operators

This commit is contained in:
Dmitriy Novozhilov
2019-10-28 16:10:10 +03:00
parent 6298889358
commit b93357be48
26 changed files with 354 additions and 68 deletions
@@ -475,6 +475,15 @@ abstract class BaseFirBuilder<T>(val session: FirSession, val context: Context =
}
}
}
if (operation in FirOperation.ASSIGNMENTS && operation != FirOperation.ASSIGN) {
return FirOperatorCallImpl(psi, operation).apply {
// TODO: take good psi
arguments += this@generateAssignment?.convert() ?: FirErrorExpressionImpl(null, "Unsupported left value of assignment: ${psi?.text}")
arguments += value
}
}
return FirVariableAssignmentImpl(psi, false, value, operation).apply {
lValue = initializeLValue(this@generateAssignment) { convert() as? FirQualifiedAccess }
}
@@ -37,6 +37,6 @@ FILE: destructuring.kt
lval <unary>: <implicit> = x#
x# = R|<local>/<unary>|.inc#()
R|<local>/<unary>|
y# *= Double(2.0)
*=(y#, Double(2.0))
z# = String()
}
@@ -1,14 +1,14 @@
FILE: modifications.kt
public? final? fun simple(): kotlin/Unit {
lvar x: <implicit> = Int(10)
x# += Int(20)
x# -= Int(5)
x# /= Int(5)
x# *= Int(10)
+=(x#, Int(20))
-=(x#, Int(5))
/=(x#, Int(5))
*=(x#, Int(10))
}
public? final? fun List<String>.modify(): kotlin/Unit {
this# += String(Alpha)
this# += String(Omega)
+=(this#, String(Alpha))
+=(this#, String(Omega))
}
public? final? fun Any.modify(): kotlin/Unit {
lval <complex-set>: <implicit> = (this# as List<Int>)
@@ -5,14 +5,16 @@
package org.jetbrains.kotlin.fir.resolve.transformers.body.resolve
import org.jetbrains.kotlin.contracts.description.InvocationKind
import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.declarations.FirAnonymousFunction
import org.jetbrains.kotlin.fir.expressions.*
import org.jetbrains.kotlin.fir.expressions.impl.FirErrorExpressionImpl
import org.jetbrains.kotlin.fir.expressions.impl.FirExpressionWithSmartcastImpl
import org.jetbrains.kotlin.fir.expressions.impl.FirFunctionCallImpl
import org.jetbrains.kotlin.fir.expressions.impl.FirVariableAssignmentImpl
import org.jetbrains.kotlin.fir.references.FirDelegateFieldReference
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
import org.jetbrains.kotlin.fir.references.FirSuperReference
import org.jetbrains.kotlin.fir.references.impl.FirErrorNamedReferenceImpl
import org.jetbrains.kotlin.fir.references.impl.FirExplicitThisReference
import org.jetbrains.kotlin.fir.references.impl.FirSimpleNamedReference
import org.jetbrains.kotlin.fir.render
@@ -27,6 +29,7 @@ import org.jetbrains.kotlin.fir.resolve.withNullability
import org.jetbrains.kotlin.fir.resolvedTypeFromPrototype
import org.jetbrains.kotlin.fir.scopes.impl.withReplacedConeType
import org.jetbrains.kotlin.fir.symbols.StandardClassIds
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
import org.jetbrains.kotlin.fir.symbols.invoke
import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.types.impl.ConeClassTypeImpl
@@ -34,11 +37,11 @@ import org.jetbrains.kotlin.fir.types.impl.FirErrorTypeRefImpl
import org.jetbrains.kotlin.fir.types.impl.FirImplicitUnitTypeRef
import org.jetbrains.kotlin.fir.types.impl.FirResolvedTypeRefImpl
import org.jetbrains.kotlin.fir.visitors.CompositeTransformResult
import org.jetbrains.kotlin.fir.visitors.FirTransformer
import org.jetbrains.kotlin.fir.visitors.compose
import org.jetbrains.kotlin.fir.visitors.transformSingle
import org.jetbrains.kotlin.ir.expressions.IrConstKind
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.Name
class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransformer) : FirPartialBodyResolveTransformer(transformer) {
private val callResolver: FirCallResolver get() = components.callResolver
@@ -187,6 +190,53 @@ class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransformer) :
} else {
transformExpression(operatorCall, data).single
} as FirOperatorCall
if (operatorCall.operation in FirOperation.ASSIGNMENTS) {
require(operatorCall.operation != FirOperation.ASSIGN)
@Suppress("NAME_SHADOWING")
val operatorCall = operatorCall.transformArguments(this, noExpectedType)
val (leftArgument, rightArgument) = operatorCall.arguments
fun createFunctionCall(name: Name) = FirFunctionCallImpl(operatorCall.psi).apply {
explicitReceiver = leftArgument
arguments += rightArgument
calleeReference = FirSimpleNamedReference(
operatorCall.psi,
name,
candidateSymbol = null
)
}
// TODO: disable DataFlowAnalyzer for resolving that two calls
// x.plusAssign(y)
val assignmentOperatorName = FirOperationNameConventions.ASSIGNMENTS.getValue(operatorCall.operation)
val assignOperatorCall = createFunctionCall(assignmentOperatorName)
val resolvedAssignCall = assignOperatorCall.transformSingle(this, noExpectedType)
val assignCallReference = resolvedAssignCall.toResolvedCallableReference()
// x + y
val simpleOperatorName = FirOperationNameConventions.ASSIGNMENTS_TO_SIMPLE_OPERATOR.getValue(operatorCall.operation)
val simpleOperatorCall = createFunctionCall(simpleOperatorName)
val resolvedOperatorCall = simpleOperatorCall.transformSingle(this, noExpectedType)
val operatorCallReference = resolvedOperatorCall.toResolvedCallableReference()
val property = (leftArgument.toResolvedCallableSymbol() as? FirPropertySymbol)?.fir
return when {
operatorCallReference == null || property?.isVal == true -> resolvedAssignCall.compose()
assignCallReference == null -> {
val assignment =
FirVariableAssignmentImpl(operatorCall.psi, false, resolvedOperatorCall, FirOperation.ASSIGN).apply {
lValue = (leftArgument as? FirQualifiedAccess)?.calleeReference
?: FirErrorNamedReferenceImpl(null, "Unresolved reference")
}
assignment.transform(transformer, noExpectedType)
}
else -> FirErrorExpressionImpl(
operatorCall.psi,
"Operator overload ambiguity. $assignmentOperatorName and $simpleOperatorName are compatible"
).compose()
}
}
dataFlowAnalyzer.exitOperatorCall(result)
return result.compose()
}
@@ -0,0 +1,14 @@
class Foo {
operator fun plus(other: Foo): Foo = this
}
fun test_1() {
val f1 = Foo()
val f2 = Foo()
val f3 = f1 + f2
}
fun test_2() {
var f = Foo()
f += Foo()
}
@@ -0,0 +1,20 @@
FILE: plus.kt
public final class Foo : R|kotlin/Any| {
public constructor(): R|Foo| {
super<R|kotlin/Any|>()
}
public final operator fun plus(other: R|Foo|): R|Foo| {
^plus this@R|/Foo|
}
}
public final fun test_1(): R|kotlin/Unit| {
lval f1: R|Foo| = R|/Foo.Foo|()
lval f2: R|Foo| = R|/Foo.Foo|()
lval f3: R|Foo| = R|<local>/f1|.R|/Foo.plus|(R|<local>/f2|)
}
public final fun test_2(): R|kotlin/Unit| {
lvar f: R|Foo| = R|/Foo.Foo|()
R|<local>/f| = R|<local>/f|.R|/Foo.plus|(R|/Foo.Foo|())
}
@@ -0,0 +1,9 @@
class Foo {
operator fun plus(f: Foo): Foo {}
operator fun plusAssign(f: Foo) {}
}
fun test() {
var f = Foo()
f += f
}
@@ -0,0 +1,17 @@
FILE: plusAndPlusAssign.kt
public final class Foo : R|kotlin/Any| {
public constructor(): R|Foo| {
super<R|kotlin/Any|>()
}
public final operator fun plus(f: R|Foo|): R|Foo| {
}
public final operator fun plusAssign(f: R|Foo|): R|kotlin/Unit| {
}
}
public final fun test(): R|kotlin/Unit| {
lvar f: R|Foo| = R|/Foo.Foo|()
ERROR_EXPR(Operator overload ambiguity. plusAssign and plus are compatible)
}
@@ -0,0 +1,22 @@
operator fun Foo.plusAssign(x: Any) {}
class Foo {
operator fun plusAssign(x: Foo) {}
operator fun plusAssign(x: String) {}
}
fun test_1() {
val f = Foo()
f + f
}
fun test_2() {
val f = Foo()
f += f
}
fun test_3(f: Foo) {
f += f
f += ""
f += 1
}
@@ -0,0 +1,28 @@
FILE: plusAssign.kt
public final operator fun R|Foo|.plusAssign(x: R|kotlin/Any|): R|kotlin/Unit| {
}
public final class Foo : R|kotlin/Any| {
public constructor(): R|Foo| {
super<R|kotlin/Any|>()
}
public final operator fun plusAssign(x: R|Foo|): R|kotlin/Unit| {
}
public final operator fun plusAssign(x: R|kotlin/String|): R|kotlin/Unit| {
}
}
public final fun test_1(): R|kotlin/Unit| {
lval f: R|Foo| = R|/Foo.Foo|()
R|<local>/f|.<Unresolved name: plus>#(R|<local>/f|)
}
public final fun test_2(): R|kotlin/Unit| {
lval f: R|Foo| = R|/Foo.Foo|()
R|<local>/f|.R|/Foo.plusAssign|(R|<local>/f|)
}
public final fun test_3(f: R|Foo|): R|kotlin/Unit| {
R|<local>/f|.R|/Foo.plusAssign|(R|<local>/f|)
R|<local>/f|.R|/Foo.plusAssign|(String())
R|<local>/f|.R|/plusAssign|(Int(1))
}
+1 -1
View File
@@ -13,7 +13,7 @@ FILE: fib.kt
while(R|<local>/<iterator>|.R|kotlin/collections/Iterator.hasNext|()) {
lval i: R|kotlin/Int| = R|<local>/<iterator>|.R|kotlin/collections/IntIterator.next|()
lval temp: R|kotlin/Int| = R|<local>/current|
R|<local>/current| += R|<local>/prev|
R|<local>/current| = R|<local>/current|.R|kotlin/Int.plus|(R|<local>/prev|)
R|<local>/prev| = R|<local>/temp|
}
@@ -476,6 +476,34 @@ public class FirResolveTestCaseGenerated extends AbstractFirResolveTestCase {
runTest("compiler/fir/resolve/testData/resolve/expresssions/invoke/threeReceivers.kt");
}
}
@TestMetadata("compiler/fir/resolve/testData/resolve/expresssions/operators")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class Operators extends AbstractFirResolveTestCase {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
}
public void testAllFilesPresentInOperators() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/fir/resolve/testData/resolve/expresssions/operators"), Pattern.compile("^([^.]+)\\.kt$"), true);
}
@TestMetadata("plus.kt")
public void testPlus() throws Exception {
runTest("compiler/fir/resolve/testData/resolve/expresssions/operators/plus.kt");
}
@TestMetadata("plusAndPlusAssign.kt")
public void testPlusAndPlusAssign() throws Exception {
runTest("compiler/fir/resolve/testData/resolve/expresssions/operators/plusAndPlusAssign.kt");
}
@TestMetadata("plusAssign.kt")
public void testPlusAssign() throws Exception {
runTest("compiler/fir/resolve/testData/resolve/expresssions/operators/plusAssign.kt");
}
}
}
@TestMetadata("compiler/fir/resolve/testData/resolve/fromBuilder")
@@ -5,6 +5,8 @@
package org.jetbrains.kotlin.fir.expressions
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.util.OperatorNameConventions
import java.util.*
enum class FirOperation(val operator: String = "???") {
@@ -46,4 +48,26 @@ enum class FirOperation(val operator: String = "???") {
val TYPES: Set<FirOperation> = EnumSet.of(IS, NOT_IS, AS, SAFE_AS)
}
}
object FirOperationNameConventions {
val ASSIGNMENTS: Map<FirOperation, Name> = EnumMap(
mapOf(
FirOperation.PLUS_ASSIGN to OperatorNameConventions.PLUS_ASSIGN,
FirOperation.MINUS_ASSIGN to OperatorNameConventions.MINUS_ASSIGN,
FirOperation.TIMES_ASSIGN to OperatorNameConventions.TIMES_ASSIGN,
FirOperation.DIV_ASSIGN to OperatorNameConventions.DIV_ASSIGN,
FirOperation.REM_ASSIGN to OperatorNameConventions.REM_ASSIGN
)
)
val ASSIGNMENTS_TO_SIMPLE_OPERATOR: Map<FirOperation, Name> = EnumMap(
mapOf(
FirOperation.PLUS_ASSIGN to OperatorNameConventions.PLUS,
FirOperation.MINUS_ASSIGN to OperatorNameConventions.MINUS,
FirOperation.TIMES_ASSIGN to OperatorNameConventions.TIMES,
FirOperation.DIV_ASSIGN to OperatorNameConventions.DIV,
FirOperation.REM_ASSIGN to OperatorNameConventions.REM
)
)
}
@@ -14,5 +14,6 @@ FILE fqName:<root> fileName:/localDelegatedProperties.kt
SET_VAR 'var x: IrErrorType [var] declared in <root>.test2' type=IrErrorType origin=null
ERROR_CALL 'Unresolved reference: <Ambiguity: inc, [kotlin/inc, kotlin/inc]>#' type=IrErrorType
GET_VAR 'val <unary>: IrErrorType [val] declared in <root>.test2' type=IrErrorType origin=null
SET_VAR 'var x: IrErrorType [var] declared in <root>.test2' type=IrErrorType origin=null
CONST Int type=IrErrorType value=1
CALL 'public final fun plusAssign (element: T of <uninitialized parent>): kotlin.Unit [inline] declared in kotlin.collections' type=kotlin.Unit origin=null
$receiver: GET_VAR 'var x: IrErrorType [var] declared in <root>.test2' type=IrErrorType origin=null
element: CONST Int type=kotlin.Int value=1
@@ -19,24 +19,44 @@ FILE fqName:<root> fileName:/augmentedAssignment1.kt
VAR name:x type:kotlin.Int [var]
CONST Int type=kotlin.Int value=0
SET_VAR 'var x: kotlin.Int [var] declared in <root>.testVariable' type=kotlin.Int origin=null
CONST Int type=kotlin.Int value=1
CALL 'public final fun plus (other: kotlin.Int): kotlin.Int declared in kotlin.Int' type=kotlin.Int origin=null
$this: GET_VAR 'var x: kotlin.Int [var] declared in <root>.testVariable' type=kotlin.Int origin=null
other: CONST Int type=kotlin.Int value=1
SET_VAR 'var x: kotlin.Int [var] declared in <root>.testVariable' type=kotlin.Int origin=null
CONST Int type=kotlin.Int value=2
CALL 'public final fun minus (other: kotlin.Int): kotlin.Int declared in kotlin.Int' type=kotlin.Int origin=null
$this: GET_VAR 'var x: kotlin.Int [var] declared in <root>.testVariable' type=kotlin.Int origin=null
other: CONST Int type=kotlin.Int value=2
SET_VAR 'var x: kotlin.Int [var] declared in <root>.testVariable' type=kotlin.Int origin=null
CONST Int type=kotlin.Int value=3
CALL 'public final fun times (other: kotlin.Int): kotlin.Int declared in kotlin.Int' type=kotlin.Int origin=null
$this: GET_VAR 'var x: kotlin.Int [var] declared in <root>.testVariable' type=kotlin.Int origin=null
other: CONST Int type=kotlin.Int value=3
SET_VAR 'var x: kotlin.Int [var] declared in <root>.testVariable' type=kotlin.Int origin=null
CONST Int type=kotlin.Int value=4
CALL 'public final fun div (other: kotlin.Int): kotlin.Int declared in kotlin.Int' type=kotlin.Int origin=null
$this: GET_VAR 'var x: kotlin.Int [var] declared in <root>.testVariable' type=kotlin.Int origin=null
other: CONST Int type=kotlin.Int value=4
SET_VAR 'var x: kotlin.Int [var] declared in <root>.testVariable' type=kotlin.Int origin=null
CONST Int type=kotlin.Int value=5
CALL 'public final fun rem (other: kotlin.Int): kotlin.Int declared in kotlin.Int' type=kotlin.Int origin=null
$this: GET_VAR 'var x: kotlin.Int [var] declared in <root>.testVariable' type=kotlin.Int origin=null
other: CONST Int type=kotlin.Int value=5
FUN name:testProperty visibility:public modality:FINAL <> () returnType:kotlin.Unit
BLOCK_BODY
SET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:p type:kotlin.Int visibility:private [static]' type=kotlin.Unit origin=null
value: CONST Int type=kotlin.Int value=1
value: CALL 'public final fun plus (other: kotlin.Int): kotlin.Int declared in kotlin.Int' type=kotlin.Int origin=null
$this: CALL 'public final fun <get-p> (): kotlin.Int declared in <root>' type=kotlin.Int origin=null
other: CONST Int type=kotlin.Int value=1
SET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:p type:kotlin.Int visibility:private [static]' type=kotlin.Unit origin=null
value: CONST Int type=kotlin.Int value=2
value: CALL 'public final fun minus (other: kotlin.Int): kotlin.Int declared in kotlin.Int' type=kotlin.Int origin=null
$this: CALL 'public final fun <get-p> (): kotlin.Int declared in <root>' type=kotlin.Int origin=null
other: CONST Int type=kotlin.Int value=2
SET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:p type:kotlin.Int visibility:private [static]' type=kotlin.Unit origin=null
value: CONST Int type=kotlin.Int value=3
value: CALL 'public final fun times (other: kotlin.Int): kotlin.Int declared in kotlin.Int' type=kotlin.Int origin=null
$this: CALL 'public final fun <get-p> (): kotlin.Int declared in <root>' type=kotlin.Int origin=null
other: CONST Int type=kotlin.Int value=3
SET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:p type:kotlin.Int visibility:private [static]' type=kotlin.Unit origin=null
value: CONST Int type=kotlin.Int value=4
value: CALL 'public final fun div (other: kotlin.Int): kotlin.Int declared in kotlin.Int' type=kotlin.Int origin=null
$this: CALL 'public final fun <get-p> (): kotlin.Int declared in <root>' type=kotlin.Int origin=null
other: CONST Int type=kotlin.Int value=4
SET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:p type:kotlin.Int visibility:private [static]' type=kotlin.Unit origin=null
value: CONST Int type=kotlin.Int value=5
value: CALL 'public final fun rem (other: kotlin.Int): kotlin.Int declared in kotlin.Int' type=kotlin.Int origin=null
$this: CALL 'public final fun <get-p> (): kotlin.Int declared in <root>' type=kotlin.Int origin=null
other: CONST Int type=kotlin.Int value=5
@@ -51,25 +51,35 @@ FILE fqName:<root> fileName:/augmentedAssignment2.kt
BLOCK_BODY
VAR name:a type:<root>.A [val]
CONSTRUCTOR_CALL 'public constructor <init> () [primary] declared in <root>.A' type=<root>.A origin=null
SET_VAR 'val a: <root>.A [val] declared in <root>.testVariable' type=<root>.A origin=null
CONST String type=<root>.A value="+="
SET_VAR 'val a: <root>.A [val] declared in <root>.testVariable' type=<root>.A origin=null
CONST String type=<root>.A value="-="
SET_VAR 'val a: <root>.A [val] declared in <root>.testVariable' type=<root>.A origin=null
CONST String type=<root>.A value="*="
SET_VAR 'val a: <root>.A [val] declared in <root>.testVariable' type=<root>.A origin=null
CONST String type=<root>.A value="/="
SET_VAR 'val a: <root>.A [val] declared in <root>.testVariable' type=<root>.A origin=null
CONST String type=<root>.A value="*="
CALL 'public final fun plusAssign (s: kotlin.String): kotlin.Unit declared in <root>' type=kotlin.Unit origin=null
$receiver: GET_VAR 'val a: <root>.A [val] declared in <root>.testVariable' type=<root>.A origin=null
s: CONST String type=kotlin.String value="+="
CALL 'public final fun minusAssign (s: kotlin.String): kotlin.Unit declared in <root>' type=kotlin.Unit origin=null
$receiver: GET_VAR 'val a: <root>.A [val] declared in <root>.testVariable' type=<root>.A origin=null
s: CONST String type=kotlin.String value="-="
CALL 'public final fun timesAssign (s: kotlin.String): kotlin.Unit declared in <root>' type=kotlin.Unit origin=null
$receiver: GET_VAR 'val a: <root>.A [val] declared in <root>.testVariable' type=<root>.A origin=null
s: CONST String type=kotlin.String value="*="
CALL 'public final fun divAssign (s: kotlin.String): kotlin.Unit declared in <root>' type=kotlin.Unit origin=null
$receiver: GET_VAR 'val a: <root>.A [val] declared in <root>.testVariable' type=<root>.A origin=null
s: CONST String type=kotlin.String value="/="
CALL 'public final fun remAssign (s: kotlin.String): kotlin.Unit declared in <root>' type=kotlin.Unit origin=null
$receiver: GET_VAR 'val a: <root>.A [val] declared in <root>.testVariable' type=<root>.A origin=null
s: CONST String type=kotlin.String value="*="
FUN name:testProperty visibility:public modality:FINAL <> () returnType:kotlin.Unit
BLOCK_BODY
SET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:p type:<root>.A visibility:private [final,static]' type=kotlin.Unit origin=null
value: CONST String type=<root>.A value="+="
SET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:p type:<root>.A visibility:private [final,static]' type=kotlin.Unit origin=null
value: CONST String type=<root>.A value="-="
SET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:p type:<root>.A visibility:private [final,static]' type=kotlin.Unit origin=null
value: CONST String type=<root>.A value="*="
SET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:p type:<root>.A visibility:private [final,static]' type=kotlin.Unit origin=null
value: CONST String type=<root>.A value="/="
SET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:p type:<root>.A visibility:private [final,static]' type=kotlin.Unit origin=null
value: CONST String type=<root>.A value="%="
CALL 'public final fun plusAssign (s: kotlin.String): kotlin.Unit declared in <root>' type=kotlin.Unit origin=null
$receiver: CALL 'public final fun <get-p> (): <root>.A declared in <root>' type=<root>.A origin=null
s: CONST String type=kotlin.String value="+="
CALL 'public final fun minusAssign (s: kotlin.String): kotlin.Unit declared in <root>' type=kotlin.Unit origin=null
$receiver: CALL 'public final fun <get-p> (): <root>.A declared in <root>' type=<root>.A origin=null
s: CONST String type=kotlin.String value="-="
CALL 'public final fun timesAssign (s: kotlin.String): kotlin.Unit declared in <root>' type=kotlin.Unit origin=null
$receiver: CALL 'public final fun <get-p> (): <root>.A declared in <root>' type=<root>.A origin=null
s: CONST String type=kotlin.String value="*="
CALL 'public final fun divAssign (s: kotlin.String): kotlin.Unit declared in <root>' type=kotlin.Unit origin=null
$receiver: CALL 'public final fun <get-p> (): <root>.A declared in <root>' type=<root>.A origin=null
s: CONST String type=kotlin.String value="/="
CALL 'public final fun remAssign (s: kotlin.String): kotlin.Unit declared in <root>' type=kotlin.Unit origin=null
$receiver: CALL 'public final fun <get-p> (): <root>.A declared in <root>' type=<root>.A origin=null
s: CONST String type=kotlin.String value="%="
@@ -12,7 +12,9 @@ FILE fqName:<root> fileName:/augmentedAssignmentWithExpression.kt
FUN name:test1 visibility:public modality:FINAL <> ($this:<root>.Host) returnType:kotlin.Unit
$this: VALUE_PARAMETER name:<this> type:<root>.Host
BLOCK_BODY
ERROR_CALL 'Unresolved reference: this#' type=IrErrorType
CALL 'public final fun plusAssign (x: kotlin.Int): kotlin.Unit declared in <root>.Host' type=kotlin.Unit origin=null
$this: GET_VAR '<this>: <root>.Host declared in <root>.Host' type=<root>.Host origin=null
x: CONST Int type=kotlin.Int value=1
FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean
overridden:
public open fun equals (other: kotlin.Any?): kotlin.Boolean declared in kotlin.Any
@@ -33,7 +35,9 @@ FILE fqName:<root> fileName:/augmentedAssignmentWithExpression.kt
FUN name:test2 visibility:public modality:FINAL <> ($receiver:<root>.Host) returnType:kotlin.Unit
$receiver: VALUE_PARAMETER name:<this> type:<root>.Host
BLOCK_BODY
ERROR_CALL 'Unresolved reference: this#' type=IrErrorType
CALL 'public final fun plusAssign (x: kotlin.Int): kotlin.Unit declared in <root>.Host' type=kotlin.Unit origin=null
$this: GET_VAR '<this>: <root>.Host declared in <root>.test2' type=<root>.Host origin=null
x: CONST Int type=kotlin.Int value=1
FUN name:test3 visibility:public modality:FINAL <> () returnType:kotlin.Unit
BLOCK_BODY
VAR name:<complex-set> type:<root>.Host [val]
@@ -122,9 +122,11 @@ FILE fqName:<root> fileName:/breakContinueInWhen.kt
arg1: CONST Int type=kotlin.Int value=2
then: CONTINUE label=null loop.label=null
SET_VAR 'var s: kotlin.String [var] declared in <root>.testContinueDoWhile' type=kotlin.String origin=null
STRING_CONCATENATION type=kotlin.String
GET_VAR 'var k: kotlin.Int [var] declared in <root>.testContinueDoWhile' type=kotlin.Int origin=null
CONST String type=kotlin.String value=";"
CALL 'public final fun plus (other: kotlin.Any?): kotlin.String declared in kotlin.String' type=kotlin.String origin=null
$this: GET_VAR 'var s: kotlin.String [var] declared in <root>.testContinueDoWhile' type=kotlin.String origin=null
other: STRING_CONCATENATION type=kotlin.String
GET_VAR 'var k: kotlin.Int [var] declared in <root>.testContinueDoWhile' type=kotlin.Int origin=null
CONST String type=kotlin.String value=";"
condition: CALL 'public final fun less (arg0: kotlin.Int, arg1: kotlin.Int): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=LT
arg0: GET_VAR 'var k: kotlin.Int [var] declared in <root>.testContinueDoWhile' type=kotlin.Int origin=null
arg1: CONST Int type=kotlin.Int value=10
@@ -219,9 +219,11 @@ FILE fqName:<root> fileName:/complexAugmentedAssignment.kt
VALUE_PARAMETER name:b index:0 type:<root>.B
BLOCK_BODY
SET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:s type:kotlin.Int visibility:private' type=kotlin.Unit origin=null
receiver: GET_VAR '<this>: <root>.B declared in <root>.Host.plusAssign' type=<root>.B origin=null
value: CALL 'public final fun <get-s> (): kotlin.Int declared in <root>.B' type=kotlin.Int origin=null
$this: GET_VAR 'b: <root>.B declared in <root>.Host.plusAssign' type=<root>.B origin=null
value: CALL 'public final fun plus (other: kotlin.Int): kotlin.Int declared in kotlin.Int' type=kotlin.Int origin=null
$this: CALL 'public final fun <get-s> (): kotlin.Int declared in <root>.B' type=kotlin.Int origin=null
$this: GET_VAR '<this>: <root>.B declared in <root>.Host.plusAssign' type=<root>.B origin=null
other: CALL 'public final fun <get-s> (): kotlin.Int declared in <root>.B' type=kotlin.Int origin=null
$this: GET_VAR 'b: <root>.B declared in <root>.Host.plusAssign' type=<root>.B origin=null
FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean
overridden:
public open fun equals (other: kotlin.Any?): kotlin.Boolean declared in kotlin.Any
@@ -239,4 +241,7 @@ FILE fqName:<root> fileName:/complexAugmentedAssignment.kt
$receiver: VALUE_PARAMETER name:<this> type:<root>.Host
VALUE_PARAMETER name:v index:0 type:<root>.B
BLOCK_BODY
ERROR_CALL 'Unresolved reference: R|<local>/v|' type=IrErrorType
CALL 'public final fun plusAssign (b: <root>.B): kotlin.Unit declared in <root>.Host' type=kotlin.Unit origin=null
$this: GET_VAR '<this>: <root>.Host declared in <root>.Host' type=<root>.Host origin=null
b: CONSTRUCTOR_CALL 'public constructor <init> (s: kotlin.Int) [primary] declared in <root>.B' type=<root>.B origin=null
s: CONST Int type=kotlin.Int value=1000
+3 -1
View File
@@ -28,4 +28,6 @@ FILE fqName:<root> fileName:/field.kt
VALUE_PARAMETER name:value index:0 type:kotlin.Int
BLOCK_BODY
SET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:testAugmented type:kotlin.Int visibility:private [static]' type=kotlin.Unit origin=null
value: GET_VAR 'value: kotlin.Int declared in <root>.<set-testAugmented>' type=kotlin.Int origin=null
value: CALL 'public final fun plus (other: kotlin.Int): kotlin.Int declared in kotlin.Int' type=kotlin.Int origin=null
$this: GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:testAugmented type:kotlin.Int visibility:private [static]' type=kotlin.Int origin=GET_PROPERTY
other: GET_VAR 'value: kotlin.Int declared in <root>.<set-testAugmented>' type=kotlin.Int origin=null
+8 -5
View File
@@ -75,12 +75,15 @@ FILE fqName:<root> fileName:/kt16904.kt
$this: VALUE_PARAMETER INSTANCE_RECEIVER name:<this> type:<root>.Test1
CONSTRUCTOR visibility:public <> () returnType:<root>.Test1
BLOCK_BODY
SET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:x type:<root>.B visibility:private [final]' type=kotlin.Unit origin=null
receiver: GET_VAR '<this>: <root>.A declared in <root>.A' type=<root>.A origin=null
value: CONST Int type=<root>.B value=42
CALL 'public final fun plusAssign (x: kotlin.Int): kotlin.Unit declared in <root>.B' type=kotlin.Unit origin=null
$this: CALL 'public final fun <get-x> (): <root>.B declared in <root>.A' type=<root>.B origin=null
$this: GET_VAR '<this>: <root>.A declared in <root>.A' type=<root>.A origin=null
x: CONST Int type=kotlin.Int value=42
SET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:y type:kotlin.Int visibility:private' type=kotlin.Unit origin=null
receiver: GET_VAR '<this>: <root>.A declared in <root>.A' type=<root>.A origin=null
value: CONST Int type=kotlin.Int value=42
value: CALL 'public final fun plus (other: kotlin.Int): kotlin.Int declared in kotlin.Int' type=kotlin.Int origin=null
$this: CALL 'public final fun <get-y> (): kotlin.Int declared in <root>.A' type=kotlin.Int origin=null
$this: GET_VAR '<this>: <root>.A declared in <root>.A' type=<root>.A origin=null
other: CONST Int type=kotlin.Int value=42
DELEGATING_CONSTRUCTOR_CALL 'public constructor <init> () [primary] declared in kotlin.Any'
INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:Test1 modality:FINAL visibility:public superTypes:[<root>.A]'
PROPERTY FAKE_OVERRIDE name:x visibility:public modality:FINAL [val]
+3 -1
View File
@@ -12,7 +12,9 @@ FILE fqName:<root> fileName:/kt24804.kt
DO_WHILE label=l2 origin=DO_WHILE_LOOP
body: BLOCK type=kotlin.Unit origin=null
SET_VAR 'var z: kotlin.Int [var] declared in <root>.run' type=kotlin.Int origin=null
CONST Int type=kotlin.Int value=1
CALL 'public final fun plus (other: kotlin.Int): kotlin.Int declared in kotlin.Int' type=kotlin.Int origin=null
$this: GET_VAR 'var z: kotlin.Int [var] declared in <root>.run' type=kotlin.Int origin=null
other: CONST Int type=kotlin.Int value=1
WHEN type=kotlin.Unit origin=IF
BRANCH
if: CALL 'public final fun greater (arg0: kotlin.Int, arg1: kotlin.Int): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=GT
+6 -2
View File
@@ -14,7 +14,9 @@ FILE fqName:<root> fileName:/kt27933.kt
if: CONST Boolean type=kotlin.Boolean value=true
then: BLOCK type=kotlin.Unit origin=null
SET_VAR 'var r: kotlin.String [var] declared in <root>.box' type=kotlin.String origin=null
CONST String type=kotlin.String value="O"
CALL 'public final fun plus (other: kotlin.Any?): kotlin.String declared in kotlin.String' type=kotlin.String origin=null
$this: GET_VAR 'var r: kotlin.String [var] declared in <root>.box' type=kotlin.String origin=null
other: CONST String type=kotlin.String value="O"
WHEN type=kotlin.Unit origin=IF
BRANCH
if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
@@ -22,6 +24,8 @@ FILE fqName:<root> fileName:/kt27933.kt
arg1: CONST String type=kotlin.String value="O"
then: BLOCK type=kotlin.Unit origin=null
SET_VAR 'var r: kotlin.String [var] declared in <root>.box' type=kotlin.String origin=null
CONST String type=kotlin.String value="K"
CALL 'public final fun plus (other: kotlin.Any?): kotlin.String declared in kotlin.String' type=kotlin.String origin=null
$this: GET_VAR 'var r: kotlin.String [var] declared in <root>.box' type=kotlin.String origin=null
other: CONST String type=kotlin.String value="K"
RETURN type=kotlin.Nothing from='public final fun box (): kotlin.String declared in <root>'
GET_VAR 'var r: kotlin.String [var] declared in <root>.box' type=kotlin.String origin=null
+7 -4
View File
@@ -24,7 +24,10 @@ FILE fqName:<root> fileName:/kt30020.kt
VALUE_PARAMETER name:x index:0 type:<root>.X
VALUE_PARAMETER name:nx index:1 type:<root>.X?
BLOCK_BODY
ERROR_CALL 'Unresolved reference: R|/X.xs|' type=IrErrorType
CALL 'public final fun plusAssign (element: T of <uninitialized parent>): kotlin.Unit [inline] declared in kotlin.collections' type=kotlin.Unit origin=null
$receiver: CALL 'public abstract fun <get-xs> (): kotlin.collections.MutableList<kotlin.Any> declared in <root>.X' type=kotlin.collections.MutableList<kotlin.Any> origin=null
$this: GET_VAR 'x: <root>.X declared in <root>.test' type=<root>.X origin=null
element: CONST Int type=kotlin.Int value=1
VAR name:<complex-set> type:kotlin.collections.MutableList<kotlin.Any> [val]
CALL 'public abstract fun f (): kotlin.collections.MutableList<kotlin.Any> declared in <root>.X' type=kotlin.collections.MutableList<kotlin.Any> origin=null
$this: GET_VAR 'x: <root>.X declared in <root>.test' type=<root>.X origin=null
@@ -79,7 +82,7 @@ FILE fqName:<root> fileName:/kt30020.kt
FUN name:testExtensionReceiver visibility:public modality:FINAL <> ($receiver:kotlin.collections.MutableList<kotlin.Any>) returnType:kotlin.Unit
$receiver: VALUE_PARAMETER name:<this> type:kotlin.collections.MutableList<kotlin.Any>
BLOCK_BODY
ERROR_CALL 'Unresolved reference: this#' type=IrErrorType
ERROR_EXPR 'Operator overload ambiguity. plusAssign and plus are compatible' type=IrErrorType
CLASS CLASS name:AML modality:ABSTRACT visibility:public superTypes:[kotlin.collections.MutableList<kotlin.Int>]
$this: VALUE_PARAMETER INSTANCE_RECEIVER name:<this> type:<root>.AML
CONSTRUCTOR visibility:public <> () returnType:<root>.AML [primary]
@@ -89,7 +92,7 @@ FILE fqName:<root> fileName:/kt30020.kt
FUN name:testExplicitThis visibility:public modality:FINAL <> ($this:<root>.AML) returnType:kotlin.Unit
$this: VALUE_PARAMETER name:<this> type:<root>.AML
BLOCK_BODY
ERROR_CALL 'Unresolved reference: this#' type=IrErrorType
ERROR_EXPR 'Operator overload ambiguity. plusAssign and plus are compatible' type=IrErrorType
CLASS CLASS name:Inner modality:FINAL visibility:public [inner] superTypes:[kotlin.Any]
$this: VALUE_PARAMETER INSTANCE_RECEIVER name:<this> type:<root>.AML.Inner
CONSTRUCTOR visibility:public <> () returnType:<root>.AML.Inner [primary]
@@ -99,7 +102,7 @@ FILE fqName:<root> fileName:/kt30020.kt
FUN name:testOuterThis visibility:public modality:FINAL <> ($this:<root>.AML.Inner) returnType:kotlin.Unit
$this: VALUE_PARAMETER name:<this> type:<root>.AML.Inner
BLOCK_BODY
ERROR_CALL 'Unresolved reference: this@AML#' type=IrErrorType
ERROR_EXPR 'Operator overload ambiguity. plusAssign and plus are compatible' type=IrErrorType
FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean
overridden:
public open fun equals (other: kotlin.Any?): kotlin.Boolean declared in kotlin.Any
@@ -17,7 +17,12 @@ FILE fqName:<root> fileName:/lambdaInCAO.kt
FUN name:test1 visibility:public modality:FINAL <> (a:kotlin.Any) returnType:kotlin.Unit
VALUE_PARAMETER name:a index:0 type:kotlin.Any
BLOCK_BODY
ERROR_CALL 'Unresolved reference: R|<local>/a|' type=IrErrorType
CALL 'public final fun plusAssign (lambda: kotlin.Function0<kotlin.Unit>): kotlin.Unit declared in <root>' type=kotlin.Unit origin=null
$receiver: GET_VAR 'a: kotlin.Any declared in <root>.test1' type=kotlin.Any origin=null
lambda: FUN_EXPR type=kotlin.Function0<kotlin.Unit> origin=LAMBDA
FUN LOCAL_FUNCTION_FOR_LAMBDA name:<anonymous> visibility:local modality:FINAL <> () returnType:kotlin.Unit
BLOCK_BODY
GET_OBJECT 'CLASS IR_EXTERNAL_DECLARATION_STUB OBJECT name:Unit modality:FINAL visibility:public superTypes:[kotlin.Any]' type=kotlin.Unit
FUN name:test2 visibility:public modality:FINAL <> (a:kotlin.Any) returnType:kotlin.Unit
VALUE_PARAMETER name:a index:0 type:kotlin.Any
BLOCK_BODY
@@ -26,5 +26,9 @@ FILE fqName:<root> fileName:/samOperators.kt
FUN name:test3 visibility:public modality:FINAL <> ($receiver:<root>.J) returnType:kotlin.Unit
$receiver: VALUE_PARAMETER name:<this> type:<root>.J
BLOCK_BODY
ERROR_CALL 'Unresolved reference: this#' type=IrErrorType
ERROR_CALL 'Unresolved reference: this#' type=IrErrorType
CALL 'public open fun plusAssign (i: java.lang.Runnable?): kotlin.Unit declared in <root>.J' type=kotlin.Unit origin=null
$this: GET_VAR '<this>: <root>.J declared in <root>.test3' type=<root>.J origin=null
i: ERROR_CALL 'Unsupported callable reference: ::<Unresolved name: f>#' type=IrErrorType
CALL 'public open fun minusAssign (i: java.lang.Runnable?): kotlin.Unit declared in <root>.J' type=kotlin.Unit origin=null
$this: GET_VAR '<this>: <root>.J declared in <root>.test3' type=<root>.J origin=null
i: ERROR_CALL 'Unsupported callable reference: ::<Unresolved name: f>#' type=IrErrorType