Safe calls.

This commit is contained in:
Dmitry Petrov
2016-08-22 18:13:21 +03:00
committed by Dmitry Petrov
parent 985f3b20c7
commit 594a553a04
69 changed files with 1567 additions and 1093 deletions
+18 -10
View File
@@ -4,11 +4,13 @@ IrFile /arrayAssignment.kt
BLOCK type=<no-type> hasResult=false operator=null
VAR val x: kotlin.IntArray
CALL .intArrayOf type=kotlin.IntArray operator=null
elements: DUMMY vararg type=kotlin.Int
CALL .set type=kotlin.Unit operator=EQ
$this: GET_VAR x type=kotlin.IntArray operator=null
index: CONST Int type=kotlin.Int value='1'
value: CONST Int type=kotlin.Int value='0'
elements: TYPE_OP operator=IMPLICIT_CAST typeOperand=kotlin.IntArray
DUMMY vararg type=kotlin.Int
BLOCK type=kotlin.Unit hasResult=false operator=EQ
CALL .set type=kotlin.Unit operator=EQ
$this: GET_VAR x type=kotlin.IntArray operator=null
index: CONST Int type=kotlin.Int value='1'
value: CONST Int type=kotlin.Int value='0'
IrFunction public fun foo(): kotlin.Int
IrExpressionBody
BLOCK type=<no-type> hasResult=false operator=null
@@ -17,8 +19,14 @@ IrFile /arrayAssignment.kt
IrFunction public fun test2(): kotlin.Unit
IrExpressionBody
BLOCK type=<no-type> hasResult=false operator=null
CALL .set type=kotlin.Unit operator=EQ
$this: CALL .intArrayOf type=kotlin.IntArray operator=null
elements: DUMMY vararg type=kotlin.Int
index: CALL .foo type=kotlin.Int operator=null
value: CONST Int type=kotlin.Int value='1'
BLOCK type=kotlin.Unit hasResult=false operator=EQ
VAR val tmp0_array: kotlin.IntArray
CALL .intArrayOf type=kotlin.IntArray operator=null
elements: TYPE_OP operator=IMPLICIT_CAST typeOperand=kotlin.IntArray
DUMMY vararg type=kotlin.Int
VAR val tmp1_index0: kotlin.Int
CALL .foo type=kotlin.Int operator=null
CALL .set type=kotlin.Unit operator=EQ
$this: GET_VAR tmp0_array type=kotlin.IntArray operator=null
index: GET_VAR tmp1_index0 type=kotlin.Int operator=null
value: CONST Int type=kotlin.Int value='1'
+10 -2
View File
@@ -1,9 +1,17 @@
fun foo(): IntArray = intArrayOf(1, 2, 3)
fun bar() = 42
class C(val x: IntArray)
fun testVariable() {
var x = foo()
x[0] += 1
foo()[0] *= 2
foo()[bar()] -= 1
}
fun testCall() {
foo()[bar()] *= 2
}
fun testMember(c: C) {
c.x[0]++
}
+27 -16
View File
@@ -4,12 +4,14 @@ IrFile /arrayAugmentedAssignment1.kt
BLOCK type=<no-type> hasResult=false operator=null
RETURN type=<no-type>
CALL .intArrayOf type=kotlin.IntArray operator=null
elements: DUMMY vararg type=kotlin.Int
elements: TYPE_OP operator=IMPLICIT_CAST typeOperand=kotlin.IntArray
DUMMY vararg type=kotlin.Int
IrFunction public fun bar(): kotlin.Int
IrExpressionBody
BLOCK type=<no-type> hasResult=false operator=null
RETURN type=<no-type>
CONST Int type=kotlin.Int value='42'
DUMMY C
IrFunction public fun testVariable(): kotlin.Unit
IrExpressionBody
BLOCK type=<no-type> hasResult=false operator=null
@@ -24,27 +26,36 @@ IrFile /arrayAugmentedAssignment1.kt
$this: GET_VAR x type=kotlin.IntArray operator=null
index: CONST Int type=kotlin.Int value='0'
other: CONST Int type=kotlin.Int value='1'
IrFunction public fun testCall(): kotlin.Unit
IrExpressionBody
BLOCK type=<no-type> hasResult=false operator=null
BLOCK type=kotlin.Unit hasResult=false operator=MULTEQ
VAR val tmp0_array: kotlin.IntArray
CALL .foo type=kotlin.IntArray operator=null
VAR val tmp1_index0: kotlin.Int
CALL .bar type=kotlin.Int operator=null
CALL .set type=kotlin.Unit operator=MULTEQ
$this: GET_VAR tmp0_array type=kotlin.IntArray operator=null
index: CONST Int type=kotlin.Int value='0'
index: GET_VAR tmp1_index0 type=kotlin.Int operator=null
value: CALL .times type=kotlin.Int operator=MULTEQ
$this: CALL .get type=kotlin.Int operator=MULTEQ
$this: GET_VAR tmp0_array type=kotlin.IntArray operator=null
index: CONST Int type=kotlin.Int value='0'
index: GET_VAR tmp1_index0 type=kotlin.Int operator=null
other: CONST Int type=kotlin.Int value='2'
BLOCK type=kotlin.Unit hasResult=false operator=MINUSEQ
VAR val tmp1_array: kotlin.IntArray
CALL .foo type=kotlin.IntArray operator=null
VAR val tmp2_index0: kotlin.Int
CALL .bar type=kotlin.Int operator=null
CALL .set type=kotlin.Unit operator=MINUSEQ
$this: GET_VAR tmp1_array type=kotlin.IntArray operator=null
index: GET_VAR tmp2_index0 type=kotlin.Int operator=null
value: CALL .minus type=kotlin.Int operator=MINUSEQ
$this: CALL .get type=kotlin.Int operator=MINUSEQ
$this: GET_VAR tmp1_array type=kotlin.IntArray operator=null
index: GET_VAR tmp2_index0 type=kotlin.Int operator=null
other: CONST Int type=kotlin.Int value='1'
IrFunction public fun testMember(/*0*/ c: C): kotlin.Unit
IrExpressionBody
BLOCK type=kotlin.Int hasResult=true operator=null
BLOCK type=kotlin.Int hasResult=true operator=POSTFIX_INCR
VAR val tmp0_array: kotlin.IntArray
CALL .<get-x> type=kotlin.IntArray operator=GET_PROPERTY
$this: GET_VAR c type=C operator=null
VAR val tmp1: kotlin.Int
CALL .get type=kotlin.Int operator=POSTFIX_INCR
$this: GET_VAR tmp0_array type=kotlin.IntArray operator=null
index: CONST Int type=kotlin.Int value='0'
CALL .set type=kotlin.Unit operator=POSTFIX_INCR
$this: GET_VAR tmp0_array type=kotlin.IntArray operator=null
index: CONST Int type=kotlin.Int value='0'
value: CALL .inc type=kotlin.Int operator=POSTFIX_INCR
$this: GET_VAR tmp1 type=kotlin.Int operator=null
GET_VAR tmp1 type=kotlin.Int operator=null
+5 -5
View File
@@ -32,21 +32,21 @@ IrFile /augmentedAssignment1.kt
BLOCK type=kotlin.Int hasResult=true operator=null
CALL .<set-p> type=kotlin.Unit operator=PLUSEQ
<set-?>: CALL .plus type=kotlin.Int operator=PLUSEQ
$this: CALL .<get-p> type=kotlin.Int operator=GET_PROPERTY
$this: CALL .<get-p> type=kotlin.Int operator=PLUSEQ
other: CONST Int type=kotlin.Int value='1'
CALL .<set-p> type=kotlin.Unit operator=MINUSEQ
<set-?>: CALL .minus type=kotlin.Int operator=MINUSEQ
$this: CALL .<get-p> type=kotlin.Int operator=GET_PROPERTY
$this: CALL .<get-p> type=kotlin.Int operator=MINUSEQ
other: CONST Int type=kotlin.Int value='2'
CALL .<set-p> type=kotlin.Unit operator=MULTEQ
<set-?>: CALL .times type=kotlin.Int operator=MULTEQ
$this: CALL .<get-p> type=kotlin.Int operator=GET_PROPERTY
$this: CALL .<get-p> type=kotlin.Int operator=MULTEQ
other: CONST Int type=kotlin.Int value='3'
CALL .<set-p> type=kotlin.Unit operator=DIVEQ
<set-?>: CALL .div type=kotlin.Int operator=DIVEQ
$this: CALL .<get-p> type=kotlin.Int operator=GET_PROPERTY
$this: CALL .<get-p> type=kotlin.Int operator=DIVEQ
other: CONST Int type=kotlin.Int value='4'
CALL .<set-p> type=kotlin.Unit operator=PERCEQ
<set-?>: CALL .mod type=kotlin.Int operator=PERCEQ
$this: CALL .<get-p> type=kotlin.Int operator=GET_PROPERTY
$this: CALL .<get-p> type=kotlin.Int operator=PERCEQ
other: CONST Int type=kotlin.Int value='5'
+5 -5
View File
@@ -42,17 +42,17 @@ IrFile /augmentedAssignment2.kt
IrExpressionBody
BLOCK type=<no-type> hasResult=false operator=null
CALL .plusAssign type=kotlin.Unit operator=PLUSEQ
$receiver: CALL .<get-p> type=A operator=GET_PROPERTY
$receiver: CALL .<get-p> type=A operator=PLUSEQ
s: CONST String type=kotlin.String value='+='
CALL .minusAssign type=kotlin.Unit operator=MINUSEQ
$receiver: CALL .<get-p> type=A operator=GET_PROPERTY
$receiver: CALL .<get-p> type=A operator=MINUSEQ
s: CONST String type=kotlin.String value='-='
CALL .timesAssign type=kotlin.Unit operator=MULTEQ
$receiver: CALL .<get-p> type=A operator=GET_PROPERTY
$receiver: CALL .<get-p> type=A operator=MULTEQ
s: CONST String type=kotlin.String value='*='
CALL .divAssign type=kotlin.Unit operator=DIVEQ
$receiver: CALL .<get-p> type=A operator=GET_PROPERTY
$receiver: CALL .<get-p> type=A operator=DIVEQ
s: CONST String type=kotlin.String value='/='
CALL .modAssign type=kotlin.Unit operator=PERCEQ
$receiver: CALL .<get-p> type=A operator=GET_PROPERTY
$receiver: CALL .<get-p> type=A operator=PERCEQ
s: CONST String type=kotlin.String value='%='
+2 -2
View File
@@ -28,7 +28,7 @@ IrFile /callWithReorderedArguments.kt
CALL .foo type=kotlin.Unit operator=null
a: CALL .noReorder1 type=kotlin.Int operator=null
b: CALL .noReorder2 type=kotlin.Int operator=null
BLOCK type=kotlin.Unit hasResult=false operator=SYNTHETIC_BLOCK
BLOCK type=kotlin.Unit hasResult=true operator=SYNTHETIC_BLOCK
VAR val tmp0_b: kotlin.Int
CALL .reordered1 type=kotlin.Int operator=null
VAR val tmp1_a: kotlin.Int
@@ -36,7 +36,7 @@ IrFile /callWithReorderedArguments.kt
CALL .foo type=kotlin.Unit operator=null
a: GET_VAR tmp1_a type=kotlin.Int operator=null
b: GET_VAR tmp0_b type=kotlin.Int operator=null
BLOCK type=kotlin.Unit hasResult=false operator=SYNTHETIC_BLOCK
BLOCK type=kotlin.Unit hasResult=true operator=SYNTHETIC_BLOCK
VAR val tmp2_a: kotlin.Int
CALL .reordered2 type=kotlin.Int operator=null
CALL .foo type=kotlin.Unit operator=null
+3 -3
View File
@@ -2,13 +2,13 @@ IrFunction public fun B.test(): kotlin.Unit
IrExpressionBody
BLOCK type=<no-type> hasResult=false operator=null
BLOCK type=<no-type> hasResult=false operator=SYNTHETIC_BLOCK
VAR val tmp0: A
VAR val tmp0_container: A
GET_OBJECT A type=A
VAR val x: kotlin.Int
CALL .component1 type=kotlin.Int operator=COMPONENT_N(index=1)
$this: $RECEIVER of: test type=B
$receiver: GET_VAR tmp0 type=A operator=null
$receiver: GET_VAR tmp0_container type=A operator=null
VAR val y: kotlin.Int
CALL .component2 type=kotlin.Int operator=COMPONENT_N(index=2)
$this: $RECEIVER of: test type=B
$receiver: GET_VAR tmp0 type=A operator=null
$receiver: GET_VAR tmp0_container type=A operator=null
+9 -2
View File
@@ -9,6 +9,13 @@ IrFile /dotQualified.kt
IrExpressionBody
BLOCK type=<no-type> hasResult=false operator=null
RETURN type=<no-type>
CALL ?.<get-length> type=kotlin.Int? operator=GET_PROPERTY
$this: TYPE_OP operator=IMPLICIT_CAST typeOperand=kotlin.String
BLOCK type=kotlin.Int? hasResult=true operator=SAFE_CALL
VAR val tmp0_safe_receiver: kotlin.String?
GET_VAR s type=kotlin.String? operator=null
WHEN type=kotlin.Int? operator=SAFE_CALL
if: CALL .EQEQ type=kotlin.Boolean operator=EQEQ
arg0: GET_VAR tmp0_safe_receiver type=kotlin.String? operator=null
arg1: CONST Null type=kotlin.Nothing? value='null'
then: CONST Null type=kotlin.Nothing? value='null'
else: CALL .<get-length> type=kotlin.Int operator=GET_PROPERTY
$this: GET_VAR tmp0_safe_receiver type=kotlin.String? operator=null
+29 -29
View File
@@ -11,22 +11,24 @@ IrFile /elvis.kt
IrExpressionBody
BLOCK type=<no-type> hasResult=false operator=null
RETURN type=<no-type>
WHEN type=kotlin.Any operator=ELVIS
if: CALL .EQEQ type=kotlin.Boolean operator=ELVIS
arg0: GET_VAR a type=kotlin.Any? operator=null
arg1: CONST Null type=kotlin.Nothing? value='null'
then: GET_VAR b type=kotlin.Any operator=null
else: GET_VAR a type=kotlin.Any? operator=null
BLOCK type=kotlin.Any hasResult=true operator=ELVIS
WHEN type=kotlin.Any operator=null
if: CALL .EQEQ type=kotlin.Boolean operator=EQEQ
arg0: GET_VAR a type=kotlin.Any? operator=null
arg1: CONST Null type=kotlin.Nothing? value='null'
then: GET_VAR b type=kotlin.Any operator=null
else: GET_VAR a type=kotlin.Any? operator=null
IrFunction public fun test2(/*0*/ a: kotlin.String?, /*1*/ b: kotlin.Any): kotlin.Any
IrExpressionBody
BLOCK type=<no-type> hasResult=false operator=null
RETURN type=<no-type>
WHEN type=kotlin.Any operator=ELVIS
if: CALL .EQEQ type=kotlin.Boolean operator=ELVIS
arg0: GET_VAR a type=kotlin.String? operator=null
arg1: CONST Null type=kotlin.Nothing? value='null'
then: GET_VAR b type=kotlin.Any operator=null
else: GET_VAR a type=kotlin.String? operator=null
BLOCK type=kotlin.Any hasResult=true operator=ELVIS
WHEN type=kotlin.Any operator=null
if: CALL .EQEQ type=kotlin.Boolean operator=EQEQ
arg0: GET_VAR a type=kotlin.String? operator=null
arg1: CONST Null type=kotlin.Nothing? value='null'
then: GET_VAR b type=kotlin.Any operator=null
else: GET_VAR a type=kotlin.String? operator=null
IrFunction public fun test3(/*0*/ a: kotlin.Any?, /*1*/ b: kotlin.Any?): kotlin.String
IrExpressionBody
BLOCK type=<no-type> hasResult=false operator=null
@@ -42,39 +44,37 @@ IrFile /elvis.kt
CONST String type=kotlin.String value=''
RETURN type=<no-type>
BLOCK type=kotlin.String hasResult=true operator=ELVIS
VAR val tmp0: kotlin.String?
TYPE_OP operator=IMPLICIT_CAST typeOperand=kotlin.String?
GET_VAR a type=kotlin.Any? operator=null
WHEN type=kotlin.String operator=ELVIS
if: CALL .EQEQ type=kotlin.Boolean operator=ELVIS
arg0: GET_VAR tmp0 type=kotlin.String? operator=null
WHEN type=kotlin.String operator=null
if: CALL .EQEQ type=kotlin.Boolean operator=EQEQ
arg0: GET_VAR a type=kotlin.Any? operator=null
arg1: CONST Null type=kotlin.Nothing? value='null'
then: TYPE_OP operator=IMPLICIT_CAST typeOperand=kotlin.String
GET_VAR b type=kotlin.Any? operator=null
else: GET_VAR tmp0 type=kotlin.String? operator=null
else: TYPE_OP operator=IMPLICIT_CAST typeOperand=kotlin.String
GET_VAR a type=kotlin.Any? operator=null
IrFunction public fun test4(/*0*/ x: kotlin.Any): kotlin.Any
IrExpressionBody
BLOCK type=<no-type> hasResult=false operator=null
RETURN type=<no-type>
BLOCK type=kotlin.Any hasResult=true operator=ELVIS
VAR val tmp0: kotlin.Any?
VAR val tmp0_elvis_lhs: kotlin.Any?
CALL .<get-p> type=kotlin.Any? operator=GET_PROPERTY
WHEN type=kotlin.Any operator=ELVIS
if: CALL .EQEQ type=kotlin.Boolean operator=ELVIS
arg0: GET_VAR tmp0 type=kotlin.Any? operator=null
WHEN type=kotlin.Any operator=null
if: CALL .EQEQ type=kotlin.Boolean operator=EQEQ
arg0: GET_VAR tmp0_elvis_lhs type=kotlin.Any? operator=null
arg1: CONST Null type=kotlin.Nothing? value='null'
then: GET_VAR x type=kotlin.Any operator=null
else: GET_VAR tmp0 type=kotlin.Any? operator=null
else: GET_VAR tmp0_elvis_lhs type=kotlin.Any? operator=null
IrFunction public fun test5(/*0*/ x: kotlin.Any): kotlin.Any
IrExpressionBody
BLOCK type=<no-type> hasResult=false operator=null
RETURN type=<no-type>
BLOCK type=kotlin.Any hasResult=true operator=ELVIS
VAR val tmp0: kotlin.Any?
VAR val tmp0_elvis_lhs: kotlin.Any?
CALL .foo type=kotlin.Any? operator=null
WHEN type=kotlin.Any operator=ELVIS
if: CALL .EQEQ type=kotlin.Boolean operator=ELVIS
arg0: GET_VAR tmp0 type=kotlin.Any? operator=null
WHEN type=kotlin.Any operator=null
if: CALL .EQEQ type=kotlin.Boolean operator=EQEQ
arg0: GET_VAR tmp0_elvis_lhs type=kotlin.Any? operator=null
arg1: CONST Null type=kotlin.Nothing? value='null'
then: GET_VAR x type=kotlin.Any operator=null
else: GET_VAR tmp0 type=kotlin.Any? operator=null
else: GET_VAR tmp0_elvis_lhs type=kotlin.Any? operator=null
+3 -10
View File
@@ -3,13 +3,6 @@ IrFile /implicitCastOnPlatformType.kt
IrExpressionBody
BLOCK type=<no-type> hasResult=false operator=null
RETURN type=<no-type>
BLOCK type=kotlin.String hasResult=true operator=IMPLICIT_NOTNULL
VAR val tmp0: kotlin.String!
CALL .getProperty type=kotlin.String! operator=null
p0: CONST String type=kotlin.String value='test'
WHEN type=kotlin.String operator=IMPLICIT_NOTNULL
if: CALL .EQEQ type=kotlin.Boolean operator=IMPLICIT_NOTNULL
arg0: GET_VAR tmp0 type=kotlin.String! operator=null
arg1: CONST Null type=kotlin.Nothing? value='null'
then: CALL .THROW_NPE type=kotlin.Nothing operator=IMPLICIT_NOTNULL
else: GET_VAR tmp0 type=kotlin.String! operator=null
TYPE_OP operator=IMPLICIT_NOTNULL typeOperand=kotlin.String
CALL .getProperty type=kotlin.String! operator=null
p0: CONST String type=kotlin.String value='test'
+9 -8
View File
@@ -5,7 +5,8 @@ IrFile /incrementDecrement.kt
IrProperty public val arr: kotlin.IntArray getter=null setter=null
IrExpressionBody
CALL .intArrayOf type=kotlin.IntArray operator=null
elements: DUMMY vararg type=kotlin.Int
elements: TYPE_OP operator=IMPLICIT_CAST typeOperand=kotlin.IntArray
DUMMY vararg type=kotlin.Int
IrFunction public fun testVarPrefix(): kotlin.Unit
IrExpressionBody
BLOCK type=<no-type> hasResult=false operator=null
@@ -38,7 +39,7 @@ IrFile /incrementDecrement.kt
GET_VAR x type=kotlin.Int operator=POSTFIX_INCR
SET_VAR x type=<no-type> operator=POSTFIX_INCR
CALL .inc type=kotlin.Int operator=POSTFIX_INCR
$this: GET_VAR tmp0 type=kotlin.Int operator=POSTFIX_INCR
$this: GET_VAR tmp0 type=kotlin.Int operator=null
GET_VAR tmp0 type=kotlin.Int operator=null
VAR val x2: kotlin.Int
BLOCK type=kotlin.Int hasResult=true operator=POSTFIX_DECR
@@ -46,7 +47,7 @@ IrFile /incrementDecrement.kt
GET_VAR x type=kotlin.Int operator=POSTFIX_DECR
SET_VAR x type=<no-type> operator=POSTFIX_DECR
CALL .dec type=kotlin.Int operator=POSTFIX_DECR
$this: GET_VAR tmp1 type=kotlin.Int operator=POSTFIX_DECR
$this: GET_VAR tmp1 type=kotlin.Int operator=null
GET_VAR tmp1 type=kotlin.Int operator=null
IrFunction public fun testPropPrefix(): kotlin.Unit
IrExpressionBody
@@ -55,7 +56,7 @@ IrFile /incrementDecrement.kt
BLOCK type=kotlin.Int hasResult=true operator=PREFIX_INCR
VAR val tmp0: kotlin.Int
CALL .inc type=kotlin.Int operator=PREFIX_INCR
$this: CALL .<get-p> type=kotlin.Int operator=GET_PROPERTY
$this: CALL .<get-p> type=kotlin.Int operator=PREFIX_INCR
CALL .<set-p> type=kotlin.Unit operator=PREFIX_INCR
<set-?>: GET_VAR tmp0 type=kotlin.Int operator=null
GET_VAR tmp0 type=kotlin.Int operator=null
@@ -63,7 +64,7 @@ IrFile /incrementDecrement.kt
BLOCK type=kotlin.Int hasResult=true operator=PREFIX_DECR
VAR val tmp1: kotlin.Int
CALL .dec type=kotlin.Int operator=PREFIX_DECR
$this: CALL .<get-p> type=kotlin.Int operator=GET_PROPERTY
$this: CALL .<get-p> type=kotlin.Int operator=PREFIX_DECR
CALL .<set-p> type=kotlin.Unit operator=PREFIX_DECR
<set-?>: GET_VAR tmp1 type=kotlin.Int operator=null
GET_VAR tmp1 type=kotlin.Int operator=null
@@ -73,16 +74,16 @@ IrFile /incrementDecrement.kt
VAR val p1: kotlin.Int
BLOCK type=kotlin.Int hasResult=true operator=POSTFIX_INCR
VAR val tmp0: kotlin.Int
CALL .<get-p> type=kotlin.Int operator=GET_PROPERTY
CALL .<get-p> type=kotlin.Int operator=POSTFIX_INCR
CALL .<set-p> type=kotlin.Unit operator=POSTFIX_INCR
<set-?>: CALL .inc type=kotlin.Int operator=POSTFIX_INCR
$this: GET_VAR tmp0 type=kotlin.Int operator=POSTFIX_INCR
$this: GET_VAR tmp0 type=kotlin.Int operator=null
GET_VAR tmp0 type=kotlin.Int operator=null
VAR val p2: kotlin.Int
BLOCK type=kotlin.Int hasResult=true operator=PREFIX_DECR
VAR val tmp1: kotlin.Int
CALL .dec type=kotlin.Int operator=PREFIX_DECR
$this: CALL .<get-p> type=kotlin.Int operator=GET_PROPERTY
$this: CALL .<get-p> type=kotlin.Int operator=PREFIX_DECR
CALL .<set-p> type=kotlin.Unit operator=PREFIX_DECR
<set-?>: GET_VAR tmp1 type=kotlin.Int operator=null
GET_VAR tmp1 type=kotlin.Int operator=null
@@ -0,0 +1,20 @@
package test
class C
var C?.p: Int
get() = 42
set(value) {}
operator fun Int?.inc(): Int? = this?.inc()
operator fun Int?.get(index: Int): Int = 42
operator fun Int?.set(index: Int, value: Int) {}
fun testProperty(nc: C?) {
nc?.p++
}
fun testArrayAccess(nc: C?) {
nc?.p[0]++
}
@@ -0,0 +1,53 @@
IrFile /safeCallWithIncrementDecrement.kt
DUMMY C
IrProperty public var test.C?.p: kotlin.Int getter=<get-p> setter=<set-p>
IrPropertyGetter public fun test.C?.<get-p>(): kotlin.Int property=p
IrExpressionBody
BLOCK type=<no-type> hasResult=false operator=null
RETURN type=<no-type>
CONST Int type=kotlin.Int value='42'
IrPropertySetter public fun test.C?.<set-p>(/*0*/ value: kotlin.Int): kotlin.Unit property=p
IrExpressionBody
BLOCK type=<no-type> hasResult=false operator=null
IrFunction public operator fun kotlin.Int?.inc(): kotlin.Int?
IrExpressionBody
BLOCK type=<no-type> hasResult=false operator=null
RETURN type=<no-type>
BLOCK type=kotlin.Int? hasResult=true operator=SAFE_CALL
VAR val tmp0_safe_receiver: kotlin.Int?
$RECEIVER of: inc type=kotlin.Int?
WHEN type=kotlin.Int? operator=SAFE_CALL
if: CALL .EQEQ type=kotlin.Boolean operator=EQEQ
arg0: GET_VAR tmp0_safe_receiver type=kotlin.Int? operator=null
arg1: CONST Null type=kotlin.Nothing? value='null'
then: CONST Null type=kotlin.Nothing? value='null'
else: CALL .inc type=kotlin.Int operator=null
$this: GET_VAR tmp0_safe_receiver type=kotlin.Int? operator=null
IrFunction public operator fun kotlin.Int?.get(/*0*/ index: kotlin.Int): kotlin.Int
IrExpressionBody
BLOCK type=<no-type> hasResult=false operator=null
RETURN type=<no-type>
CONST Int type=kotlin.Int value='42'
IrFunction public operator fun kotlin.Int?.set(/*0*/ index: kotlin.Int, /*1*/ value: kotlin.Int): kotlin.Unit
IrExpressionBody
BLOCK type=<no-type> hasResult=false operator=null
IrFunction public fun testProperty(/*0*/ nc: test.C?): kotlin.Unit
IrExpressionBody
BLOCK type=kotlin.Int? hasResult=true operator=null
BLOCK type=kotlin.Int? hasResult=true operator=SAFE_CALL
VAR val tmp0_safe_receiver: test.C?
GET_VAR nc type=test.C? operator=null
WHEN type=kotlin.Int? operator=SAFE_CALL
if: CALL .EQEQ type=kotlin.Boolean operator=EQEQ
arg0: GET_VAR tmp0_safe_receiver type=test.C? operator=null
arg1: CONST Null type=kotlin.Nothing? value='null'
then: CONST Null type=kotlin.Nothing? value='null'
else: BLOCK type=kotlin.Int hasResult=true operator=POSTFIX_INCR
VAR val tmp1: kotlin.Int
CALL .<get-p> type=kotlin.Int operator=POSTFIX_INCR
$this: GET_VAR tmp0_safe_receiver type=test.C? operator=null
CALL .<set-p> type=kotlin.Unit operator=POSTFIX_INCR
$this: GET_VAR tmp0_safe_receiver type=test.C? operator=null
value: CALL .inc type=kotlin.Int? operator=POSTFIX_INCR
$receiver: GET_VAR tmp1 type=kotlin.Int operator=null
GET_VAR tmp1 type=kotlin.Int operator=null
+15
View File
@@ -0,0 +1,15 @@
class Ref(var value: Int)
interface IHost {
fun String.extLength() = length
}
fun test1(x: String?) = x?.length
fun test2(x: String?) = x?.hashCode()
fun test3(x: String?, y: Any?) = x?.equals(y)
fun test4(x: Ref?) {
x?.value = 0
}
fun IHost.test5(s: String?) = s?.extLength()
+75
View File
@@ -0,0 +1,75 @@
IrFile /safeCalls.kt
DUMMY Ref
DUMMY IHost
IrFunction public fun test1(/*0*/ x: kotlin.String?): kotlin.Int?
IrExpressionBody
BLOCK type=<no-type> hasResult=false operator=null
RETURN type=<no-type>
BLOCK type=kotlin.Int? hasResult=true operator=SAFE_CALL
VAR val tmp0_safe_receiver: kotlin.String?
GET_VAR x type=kotlin.String? operator=null
WHEN type=kotlin.Int? operator=SAFE_CALL
if: CALL .EQEQ type=kotlin.Boolean operator=EQEQ
arg0: GET_VAR tmp0_safe_receiver type=kotlin.String? operator=null
arg1: CONST Null type=kotlin.Nothing? value='null'
then: CONST Null type=kotlin.Nothing? value='null'
else: CALL .<get-length> type=kotlin.Int operator=GET_PROPERTY
$this: GET_VAR tmp0_safe_receiver type=kotlin.String? operator=null
IrFunction public fun test2(/*0*/ x: kotlin.String?): kotlin.Int?
IrExpressionBody
BLOCK type=<no-type> hasResult=false operator=null
RETURN type=<no-type>
BLOCK type=kotlin.Int? hasResult=true operator=SAFE_CALL
VAR val tmp0_safe_receiver: kotlin.String?
GET_VAR x type=kotlin.String? operator=null
WHEN type=kotlin.Int? operator=SAFE_CALL
if: CALL .EQEQ type=kotlin.Boolean operator=EQEQ
arg0: GET_VAR tmp0_safe_receiver type=kotlin.String? operator=null
arg1: CONST Null type=kotlin.Nothing? value='null'
then: CONST Null type=kotlin.Nothing? value='null'
else: CALL .hashCode type=kotlin.Int operator=null
$this: GET_VAR tmp0_safe_receiver type=kotlin.String? operator=null
IrFunction public fun test3(/*0*/ x: kotlin.String?, /*1*/ y: kotlin.Any?): kotlin.Boolean?
IrExpressionBody
BLOCK type=<no-type> hasResult=false operator=null
RETURN type=<no-type>
BLOCK type=kotlin.Boolean? hasResult=true operator=SAFE_CALL
VAR val tmp0_safe_receiver: kotlin.String?
GET_VAR x type=kotlin.String? operator=null
WHEN type=kotlin.Boolean? operator=SAFE_CALL
if: CALL .EQEQ type=kotlin.Boolean operator=EQEQ
arg0: GET_VAR tmp0_safe_receiver type=kotlin.String? operator=null
arg1: CONST Null type=kotlin.Nothing? value='null'
then: CONST Null type=kotlin.Nothing? value='null'
else: CALL .equals type=kotlin.Boolean operator=null
$this: GET_VAR tmp0_safe_receiver type=kotlin.String? operator=null
other: GET_VAR y type=kotlin.Any? operator=null
IrFunction public fun test4(/*0*/ x: Ref?): kotlin.Unit
IrExpressionBody
BLOCK type=<no-type> hasResult=false operator=null
BLOCK type=kotlin.Unit? hasResult=true operator=SAFE_CALL
VAR val tmp0_safe_receiver: Ref?
GET_VAR x type=Ref? operator=null
WHEN type=kotlin.Unit? operator=SAFE_CALL
if: CALL .EQEQ type=kotlin.Boolean operator=EQEQ
arg0: GET_VAR tmp0_safe_receiver type=Ref? operator=null
arg1: CONST Null type=kotlin.Nothing? value='null'
then: CONST Null type=kotlin.Nothing? value='null'
else: CALL .<set-value> type=kotlin.Unit operator=EQ
$this: GET_VAR tmp0_safe_receiver type=Ref? operator=null
<set-?>: CONST Int type=kotlin.Int value='0'
IrFunction public fun IHost.test5(/*0*/ s: kotlin.String?): kotlin.Int?
IrExpressionBody
BLOCK type=<no-type> hasResult=false operator=null
RETURN type=<no-type>
BLOCK type=kotlin.Int? hasResult=true operator=SAFE_CALL
VAR val tmp0_safe_receiver: kotlin.String?
GET_VAR s type=kotlin.String? operator=null
WHEN type=kotlin.Int? operator=SAFE_CALL
if: CALL .EQEQ type=kotlin.Boolean operator=EQEQ
arg0: GET_VAR tmp0_safe_receiver type=kotlin.String? operator=null
arg1: CONST Null type=kotlin.Nothing? value='null'
then: CONST Null type=kotlin.Nothing? value='null'
else: CALL .extLength type=kotlin.Int operator=null
$this: $RECEIVER of: test5 type=IHost
$receiver: GET_VAR tmp0_safe_receiver type=kotlin.String? operator=null
@@ -19,12 +19,10 @@ IrFile /smartCastsWithDestructuring.kt
GET_VAR x type=I1 operator=null
then: RETURN type=<no-type>
BLOCK type=<no-type> hasResult=false operator=SYNTHETIC_BLOCK
VAR val tmp0: I1
GET_VAR x type=I1 operator=null
VAR val c1: kotlin.Int
CALL .component1 type=kotlin.Int operator=COMPONENT_N(index=1)
$receiver: GET_VAR tmp0 type=I1 operator=null
$receiver: GET_VAR x type=I1 operator=null
VAR val c2: kotlin.String
CALL .component2 type=kotlin.String operator=COMPONENT_N(index=2)
$receiver: TYPE_OP operator=IMPLICIT_CAST typeOperand=I2
GET_VAR tmp0 type=I1 operator=null
GET_VAR x type=I1 operator=null
+2 -4
View File
@@ -21,8 +21,7 @@ IrFile /when.kt
then: CONST String type=kotlin.String value='String'
if: CALL .contains type=kotlin.Boolean operator=IN
$receiver: CALL .setOf type=kotlin.collections.Set<kotlin.Nothing> operator=null
element: TYPE_OP operator=IMPLICIT_CAST typeOperand=kotlin.Any
GET_VAR tmp0_subject type=kotlin.Any? operator=null
element: GET_VAR tmp0_subject type=kotlin.Any? operator=null
then: CONST String type=kotlin.String value='nothingness?'
else: CONST String type=kotlin.String value='something'
IrFunction public fun test(/*0*/ x: kotlin.Any?): kotlin.String
@@ -43,8 +42,7 @@ IrFile /when.kt
then: CONST String type=kotlin.String value='String'
if: CALL .contains type=kotlin.Boolean operator=IN
$receiver: CALL .setOf type=kotlin.collections.Set<kotlin.Nothing> operator=null
element: TYPE_OP operator=IMPLICIT_CAST typeOperand=kotlin.Any
GET_VAR x type=kotlin.Any? operator=null
element: GET_VAR x type=kotlin.Any? operator=null
then: CONST String type=kotlin.String value='nothingness?'
else: CONST String type=kotlin.String value='something'
IrFunction public fun testComma(/*0*/ x: kotlin.Int): kotlin.String