[FE] Preserve legacy contract description calls in bodies

^KT-55231 Fixed
^KTIJ-21012 Fixed
This commit is contained in:
Yan Zhulanow
2022-12-02 17:44:31 +09:00
committed by Space Team
parent f067f64255
commit d652dc620c
103 changed files with 4258 additions and 3201 deletions
@@ -9,100 +9,107 @@ digraph inAnonymousObject_kt {
subgraph cluster_1 {
color=blue
1 [label="Enter block"];
2 [label="Enter anonymous object"];
subgraph cluster_2 {
color=blue
11 [label="Enter class <anonymous object>" style="filled" fillcolor=red];
12 [label="Part of class initialization"];
13 [label="Part of class initialization"];
14 [label="Exit class <anonymous object>" style="filled" fillcolor=red];
2 [label="Enter block"];
3 [label="Exit block"];
}
3 [label="Exit anonymous object"];
4 [label="Exit anonymous object expression"];
5 [label="Variable declaration: lval obj: R|<anonymous>|"];
6 [label="Access variable R|<local>/obj|"];
7 [label="Function call: R|<local>/obj|.R|/<anonymous>.run|()" style="filled" fillcolor=yellow];
8 [label="Function call: R|<local>/d|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()" style="filled" fillcolor=yellow];
9 [label="Exit block"];
4 [label="Enter anonymous object"];
subgraph cluster_3 {
color=blue
13 [label="Enter class <anonymous object>" style="filled" fillcolor=red];
14 [label="Part of class initialization"];
15 [label="Part of class initialization"];
16 [label="Exit class <anonymous object>" style="filled" fillcolor=red];
}
5 [label="Exit anonymous object"];
6 [label="Exit anonymous object expression"];
7 [label="Variable declaration: lval obj: R|<anonymous>|"];
8 [label="Access variable R|<local>/obj|"];
9 [label="Function call: R|<local>/obj|.R|/<anonymous>.run|()" style="filled" fillcolor=yellow];
10 [label="Function call: R|<local>/d|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()" style="filled" fillcolor=yellow];
11 [label="Exit block"];
}
10 [label="Exit function foo" style="filled" fillcolor=red];
12 [label="Exit function foo" style="filled" fillcolor=red];
}
0 -> {1};
1 -> {2};
1 -> {15 18 21 27} [color=red];
2 -> {3} [color=red];
2 -> {11} [color=green];
2 -> {11} [style=dashed];
2 -> {3};
3 -> {4};
3 -> {15 27} [color=green];
3 -> {15 27} [style=dashed];
4 -> {5};
3 -> {37 40 43 49} [color=red];
4 -> {5} [color=red];
4 -> {13} [color=green];
4 -> {13} [style=dashed];
5 -> {6};
5 -> {37 49} [color=green];
5 -> {37 49} [style=dashed];
6 -> {7};
7 -> {8};
8 -> {9};
9 -> {10};
11 -> {12} [color=green];
12 -> {13} [style=dotted];
12 -> {18} [color=green];
12 -> {18} [style=dashed];
13 -> {14} [style=dotted];
13 -> {21} [color=green];
13 -> {21} [style=dashed];
14 -> {3} [color=green];
subgraph cluster_3 {
color=red
15 [label="Enter function <init>" style="filled" fillcolor=red];
16 [label="Delegated constructor call: super<R|kotlin/Any|>()" style="filled" fillcolor=yellow];
17 [label="Exit function <init>" style="filled" fillcolor=red];
}
15 -> {16};
16 -> {17};
10 -> {11};
11 -> {12};
13 -> {14} [color=green];
14 -> {15} [style=dotted];
14 -> {40} [color=green];
14 -> {40} [style=dashed];
15 -> {16} [style=dotted];
15 -> {43} [color=green];
15 -> {43} [style=dashed];
16 -> {5} [color=green];
subgraph cluster_4 {
color=red
18 [label="Enter property" style="filled" fillcolor=red];
19 [label="Access variable R|<local>/a|"];
20 [label="Exit property" style="filled" fillcolor=red];
37 [label="Enter function <init>" style="filled" fillcolor=red];
38 [label="Delegated constructor call: super<R|kotlin/Any|>()" style="filled" fillcolor=yellow];
39 [label="Exit function <init>" style="filled" fillcolor=red];
}
18 -> {19};
19 -> {20};
20 -> {13} [color=green];
37 -> {38};
38 -> {39};
subgraph cluster_5 {
color=red
21 [label="Enter init block" style="filled" fillcolor=red];
subgraph cluster_6 {
color=blue
22 [label="Enter block"];
23 [label="Access variable R|<local>/b|"];
24 [label="Assignment: R|/<anonymous>.leaked|"];
25 [label="Exit block"];
}
26 [label="Exit init block" style="filled" fillcolor=red];
40 [label="Enter property" style="filled" fillcolor=red];
41 [label="Access variable R|<local>/a|"];
42 [label="Exit property" style="filled" fillcolor=red];
}
21 -> {22};
22 -> {23};
23 -> {24};
24 -> {25};
25 -> {26};
26 -> {14} [color=green];
40 -> {41};
41 -> {42};
42 -> {15} [color=green];
subgraph cluster_7 {
subgraph cluster_6 {
color=red
27 [label="Enter function run" style="filled" fillcolor=red];
subgraph cluster_8 {
43 [label="Enter init block" style="filled" fillcolor=red];
subgraph cluster_7 {
color=blue
28 [label="Enter block"];
29 [label="Function call: R|<local>/c|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()" style="filled" fillcolor=yellow];
30 [label="Exit block"];
44 [label="Enter block"];
45 [label="Access variable R|<local>/b|"];
46 [label="Assignment: R|/<anonymous>.leaked|"];
47 [label="Exit block"];
}
31 [label="Exit function run" style="filled" fillcolor=red];
48 [label="Exit init block" style="filled" fillcolor=red];
}
27 -> {28};
28 -> {29};
29 -> {30};
30 -> {31};
43 -> {44};
44 -> {45};
45 -> {46};
46 -> {47};
47 -> {48};
48 -> {16} [color=green];
subgraph cluster_8 {
color=red
49 [label="Enter function run" style="filled" fillcolor=red];
subgraph cluster_9 {
color=blue
50 [label="Enter block"];
51 [label="Function call: R|<local>/c|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()" style="filled" fillcolor=yellow];
52 [label="Exit block"];
}
53 [label="Exit function run" style="filled" fillcolor=red];
}
49 -> {50};
50 -> {51};
51 -> {52};
52 -> {53};
}
@@ -8,7 +8,16 @@ FILE: inAnonymousObject.kt
CallsInPlace(d, AT_MOST_ONCE)
>
{
[StubStatement]
{
R|kotlin/contracts/contract|(<L> = contract@fun R|kotlin/contracts/ContractBuilder|.<anonymous>(): R|kotlin/Unit| <inline=Inline, kind=UNKNOWN> {
this@R|special/anonymous|.R|kotlin/contracts/ContractBuilder.callsInPlace|<R|kotlin/Unit|>(R|<local>/a|, Q|kotlin/contracts/InvocationKind|.R|kotlin/contracts/InvocationKind.AT_MOST_ONCE|)
this@R|special/anonymous|.R|kotlin/contracts/ContractBuilder.callsInPlace|<R|kotlin/Unit|>(R|<local>/b|, Q|kotlin/contracts/InvocationKind|.R|kotlin/contracts/InvocationKind.AT_MOST_ONCE|)
this@R|special/anonymous|.R|kotlin/contracts/ContractBuilder.callsInPlace|<R|kotlin/Unit|>(R|<local>/c|, Q|kotlin/contracts/InvocationKind|.R|kotlin/contracts/InvocationKind.AT_MOST_ONCE|)
this@R|special/anonymous|.R|kotlin/contracts/ContractBuilder.callsInPlace|<R|kotlin/Unit|>(R|<local>/d|, Q|kotlin/contracts/InvocationKind|.R|kotlin/contracts/InvocationKind.AT_MOST_ONCE|)
}
)
}
lval obj: R|<anonymous>| = object : R|java/lang/Runnable| {
private constructor(): R|<anonymous>| {
super<R|kotlin/Any|>()
@@ -9,100 +9,107 @@ digraph inLocalClass_kt {
subgraph cluster_1 {
color=blue
1 [label="Enter block"];
2 [label="Exit local class foo"];
3 [label="Function call: R|/LocalClass.LocalClass|()" style="filled" fillcolor=yellow];
4 [label="Function call: R|/LocalClass.LocalClass|().R|<local>/run|()" style="filled" fillcolor=yellow];
5 [label="Function call: R|<local>/e|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()" style="filled" fillcolor=yellow];
6 [label="Exit block"];
subgraph cluster_2 {
color=blue
2 [label="Enter block"];
3 [label="Exit block"];
}
4 [label="Exit local class foo"];
5 [label="Function call: R|/LocalClass.LocalClass|()" style="filled" fillcolor=yellow];
6 [label="Function call: R|/LocalClass.LocalClass|().R|<local>/run|()" style="filled" fillcolor=yellow];
7 [label="Function call: R|<local>/e|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()" style="filled" fillcolor=yellow];
8 [label="Exit block"];
}
7 [label="Exit function foo" style="filled" fillcolor=red];
9 [label="Exit function foo" style="filled" fillcolor=red];
}
subgraph cluster_2 {
subgraph cluster_3 {
color=blue
8 [label="Enter class LocalClass" style="filled" fillcolor=red];
9 [label="Part of class initialization"];
10 [label="Part of class initialization"];
11 [label="Exit class LocalClass" style="filled" fillcolor=red];
10 [label="Enter class LocalClass" style="filled" fillcolor=red];
11 [label="Part of class initialization"];
12 [label="Part of class initialization"];
13 [label="Exit class LocalClass" style="filled" fillcolor=red];
}
0 -> {1};
1 -> {2};
1 -> {12 15 21 27} [color=red];
2 -> {3};
2 -> {15 27 8} [color=green];
2 -> {15 27 8} [style=dashed];
3 -> {4};
3 -> {38 41 47 53} [color=red];
4 -> {5};
4 -> {41 53 10} [color=green];
4 -> {41 53 10} [style=dashed];
5 -> {6};
6 -> {7};
8 -> {9} [color=green];
9 -> {10} [style=dotted];
9 -> {12} [color=green];
9 -> {12} [style=dashed];
10 -> {11} [style=dotted];
10 -> {21} [color=green];
10 -> {21} [style=dashed];
subgraph cluster_3 {
color=red
12 [label="Enter property" style="filled" fillcolor=red];
13 [label="Access variable R|<local>/a|"];
14 [label="Exit property" style="filled" fillcolor=red];
}
12 -> {13};
13 -> {14};
14 -> {10} [color=green];
7 -> {8};
8 -> {9};
10 -> {11} [color=green];
11 -> {12} [style=dotted];
11 -> {38} [color=green];
11 -> {38} [style=dashed];
12 -> {13} [style=dotted];
12 -> {47} [color=green];
12 -> {47} [style=dashed];
subgraph cluster_4 {
color=red
15 [label="Enter function <init>" style="filled" fillcolor=red];
16 [label="Delegated constructor call: super<R|kotlin/Any|>()" style="filled" fillcolor=yellow];
subgraph cluster_5 {
color=blue
17 [label="Enter block"];
18 [label="Function call: R|<local>/b|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()" style="filled" fillcolor=yellow];
19 [label="Exit block"];
}
20 [label="Exit function <init>" style="filled" fillcolor=red];
38 [label="Enter property" style="filled" fillcolor=red];
39 [label="Access variable R|<local>/a|"];
40 [label="Exit property" style="filled" fillcolor=red];
}
15 -> {16};
16 -> {17};
17 -> {18};
18 -> {19};
19 -> {20};
38 -> {39};
39 -> {40};
40 -> {12} [color=green];
subgraph cluster_6 {
subgraph cluster_5 {
color=red
21 [label="Enter init block" style="filled" fillcolor=red];
subgraph cluster_7 {
41 [label="Enter function <init>" style="filled" fillcolor=red];
42 [label="Delegated constructor call: super<R|kotlin/Any|>()" style="filled" fillcolor=yellow];
subgraph cluster_6 {
color=blue
22 [label="Enter block"];
23 [label="Access variable R|<local>/c|"];
24 [label="Assignment: R|<local>/leaked|"];
25 [label="Exit block"];
43 [label="Enter block"];
44 [label="Function call: R|<local>/b|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()" style="filled" fillcolor=yellow];
45 [label="Exit block"];
}
26 [label="Exit init block" style="filled" fillcolor=red];
46 [label="Exit function <init>" style="filled" fillcolor=red];
}
21 -> {22};
22 -> {23};
23 -> {24};
24 -> {25};
25 -> {26};
26 -> {11} [color=green];
41 -> {42};
42 -> {43};
43 -> {44};
44 -> {45};
45 -> {46};
subgraph cluster_8 {
subgraph cluster_7 {
color=red
27 [label="Enter function run" style="filled" fillcolor=red];
subgraph cluster_9 {
47 [label="Enter init block" style="filled" fillcolor=red];
subgraph cluster_8 {
color=blue
28 [label="Enter block"];
29 [label="Function call: R|<local>/d|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()" style="filled" fillcolor=yellow];
30 [label="Exit block"];
48 [label="Enter block"];
49 [label="Access variable R|<local>/c|"];
50 [label="Assignment: R|<local>/leaked|"];
51 [label="Exit block"];
}
31 [label="Exit function run" style="filled" fillcolor=red];
52 [label="Exit init block" style="filled" fillcolor=red];
}
27 -> {28};
28 -> {29};
29 -> {30};
30 -> {31};
47 -> {48};
48 -> {49};
49 -> {50};
50 -> {51};
51 -> {52};
52 -> {13} [color=green];
subgraph cluster_9 {
color=red
53 [label="Enter function run" style="filled" fillcolor=red];
subgraph cluster_10 {
color=blue
54 [label="Enter block"];
55 [label="Function call: R|<local>/d|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()" style="filled" fillcolor=yellow];
56 [label="Exit block"];
}
57 [label="Exit function run" style="filled" fillcolor=red];
}
53 -> {54};
54 -> {55};
55 -> {56};
56 -> {57};
}
@@ -9,7 +9,17 @@ FILE: inLocalClass.kt
CallsInPlace(e, AT_MOST_ONCE)
>
{
[StubStatement]
{
R|kotlin/contracts/contract|(<L> = contract@fun R|kotlin/contracts/ContractBuilder|.<anonymous>(): R|kotlin/Unit| <inline=Inline, kind=UNKNOWN> {
this@R|special/anonymous|.R|kotlin/contracts/ContractBuilder.callsInPlace|<R|kotlin/Unit|>(R|<local>/a|, Q|kotlin/contracts/InvocationKind|.R|kotlin/contracts/InvocationKind.AT_MOST_ONCE|)
this@R|special/anonymous|.R|kotlin/contracts/ContractBuilder.callsInPlace|<R|kotlin/Unit|>(R|<local>/b|, Q|kotlin/contracts/InvocationKind|.R|kotlin/contracts/InvocationKind.AT_MOST_ONCE|)
this@R|special/anonymous|.R|kotlin/contracts/ContractBuilder.callsInPlace|<R|kotlin/Unit|>(R|<local>/c|, Q|kotlin/contracts/InvocationKind|.R|kotlin/contracts/InvocationKind.AT_MOST_ONCE|)
this@R|special/anonymous|.R|kotlin/contracts/ContractBuilder.callsInPlace|<R|kotlin/Unit|>(R|<local>/d|, Q|kotlin/contracts/InvocationKind|.R|kotlin/contracts/InvocationKind.AT_MOST_ONCE|)
this@R|special/anonymous|.R|kotlin/contracts/ContractBuilder.callsInPlace|<R|kotlin/Unit|>(R|<local>/e|, Q|kotlin/contracts/InvocationKind|.R|kotlin/contracts/InvocationKind.AT_MOST_ONCE|)
}
)
}
local final class LocalClass : R|kotlin/Any| {
public final val leakedVal: R|() -> kotlin/Unit| = R|<local>/a|
public get(): R|() -> kotlin/Unit|
@@ -9,38 +9,45 @@ digraph inLocalFunction_kt {
subgraph cluster_1 {
color=blue
1 [label="Enter block"];
2 [label="Local function declaration foo"];
3 [label="Function call: R|<local>/localFun|()" style="filled" fillcolor=yellow];
4 [label="Function call: R|<local>/b|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()" style="filled" fillcolor=yellow];
5 [label="Exit block"];
subgraph cluster_2 {
color=blue
2 [label="Enter block"];
3 [label="Exit block"];
}
4 [label="Local function declaration foo"];
5 [label="Function call: R|<local>/localFun|()" style="filled" fillcolor=yellow];
6 [label="Function call: R|<local>/b|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()" style="filled" fillcolor=yellow];
7 [label="Exit block"];
}
6 [label="Exit function foo" style="filled" fillcolor=red];
8 [label="Exit function foo" style="filled" fillcolor=red];
}
subgraph cluster_2 {
subgraph cluster_3 {
color=blue
7 [label="Enter function localFun" style="filled" fillcolor=red];
subgraph cluster_3 {
9 [label="Enter function localFun" style="filled" fillcolor=red];
subgraph cluster_4 {
color=blue
8 [label="Enter block"];
9 [label="Access variable R|<local>/a|"];
10 [label="Function call: R|<local>/a|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()" style="filled" fillcolor=yellow];
11 [label="Function call: R|<local>/a|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()" style="filled" fillcolor=yellow];
12 [label="Exit block"];
10 [label="Enter block"];
11 [label="Access variable R|<local>/a|"];
12 [label="Function call: R|<local>/a|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()" style="filled" fillcolor=yellow];
13 [label="Function call: R|<local>/a|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()" style="filled" fillcolor=yellow];
14 [label="Exit block"];
}
13 [label="Exit function localFun" style="filled" fillcolor=red];
15 [label="Exit function localFun" style="filled" fillcolor=red];
}
0 -> {1};
1 -> {2};
2 -> {7 3};
2 -> {7} [style=dashed];
2 -> {3};
3 -> {4};
4 -> {5};
4 -> {9 5};
4 -> {9} [style=dashed];
5 -> {6};
6 -> {7};
7 -> {8};
8 -> {9};
9 -> {10};
10 -> {11};
11 -> {12};
12 -> {13};
13 -> {14};
14 -> {15};
}
@@ -5,7 +5,13 @@ FILE: inLocalFunction.kt
CallsInPlace(a, AT_MOST_ONCE)
>
{
[StubStatement]
{
R|kotlin/contracts/contract|(<L> = contract@fun R|kotlin/contracts/ContractBuilder|.<anonymous>(): R|kotlin/Unit| <inline=Inline, kind=UNKNOWN> {
this@R|special/anonymous|.R|kotlin/contracts/ContractBuilder.callsInPlace|<R|kotlin/Unit|>(R|<local>/a|, Q|kotlin/contracts/InvocationKind|.R|kotlin/contracts/InvocationKind.AT_MOST_ONCE|)
}
)
}
local final fun localFun(): R|kotlin/Unit| {
R|<local>/a|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()
R|<local>/a|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()
@@ -25,64 +25,69 @@ digraph toLocalVariables_kt {
5 [label="Enter block"];
subgraph cluster_4 {
color=blue
6 [label="Enter when"];
subgraph cluster_5 {
color=blue
7 [label="Enter when branch condition "];
8 [label="Const: Boolean(true)"];
9 [label="Exit when branch condition"];
}
6 [label="Enter block"];
7 [label="Exit block"];
}
subgraph cluster_5 {
color=blue
8 [label="Enter when"];
subgraph cluster_6 {
color=blue
10 [label="Enter when branch condition else"];
9 [label="Enter when branch condition "];
10 [label="Const: Boolean(true)"];
11 [label="Exit when branch condition"];
}
12 [label="Enter when branch result"];
subgraph cluster_7 {
color=blue
13 [label="Enter block"];
14 [label="Access variable R|<local>/y|"];
15 [label="Variable declaration: lval yCopy: R|() -> kotlin/Unit|"];
16 [label="Function call: R|<local>/yCopy|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()" style="filled" fillcolor=yellow];
17 [label="Exit block"];
12 [label="Enter when branch condition else"];
13 [label="Exit when branch condition"];
}
18 [label="Exit when branch result"];
19 [label="Enter when branch result"];
14 [label="Enter when branch result"];
subgraph cluster_8 {
color=blue
20 [label="Enter block"];
21 [label="Access variable R|<local>/x|"];
22 [label="Function call: R|/bar|(...)" style="filled" fillcolor=yellow];
23 [label="Exit block"];
15 [label="Enter block"];
16 [label="Access variable R|<local>/y|"];
17 [label="Variable declaration: lval yCopy: R|() -> kotlin/Unit|"];
18 [label="Function call: R|<local>/yCopy|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()" style="filled" fillcolor=yellow];
19 [label="Exit block"];
}
24 [label="Exit when branch result"];
25 [label="Exit when"];
20 [label="Exit when branch result"];
21 [label="Enter when branch result"];
subgraph cluster_9 {
color=blue
22 [label="Enter block"];
23 [label="Access variable R|<local>/x|"];
24 [label="Function call: R|/bar|(...)" style="filled" fillcolor=yellow];
25 [label="Exit block"];
}
26 [label="Exit when branch result"];
27 [label="Exit when"];
}
26 [label="Variable declaration: lval zCopy: R|() -> kotlin/Unit|"];
27 [label="Access variable R|<local>/z|"];
28 [label="Assignment: R|<local>/zCopy|"];
29 [label="Function call: R|<local>/zCopy|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()" style="filled" fillcolor=yellow];
30 [label="Exit block"];
28 [label="Variable declaration: lval zCopy: R|() -> kotlin/Unit|"];
29 [label="Access variable R|<local>/z|"];
30 [label="Assignment: R|<local>/zCopy|"];
31 [label="Function call: R|<local>/zCopy|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()" style="filled" fillcolor=yellow];
32 [label="Exit block"];
}
31 [label="Exit function foo" style="filled" fillcolor=red];
33 [label="Exit function foo" style="filled" fillcolor=red];
}
4 -> {5};
5 -> {6};
6 -> {7};
7 -> {8};
8 -> {9};
9 -> {19 10};
9 -> {10};
10 -> {11};
11 -> {12};
11 -> {21 12};
12 -> {13};
13 -> {14};
14 -> {15};
15 -> {16};
16 -> {17};
17 -> {18};
18 -> {25};
18 -> {19};
19 -> {20};
20 -> {21};
20 -> {27};
21 -> {22};
22 -> {23};
23 -> {24};
@@ -93,5 +98,7 @@ digraph toLocalVariables_kt {
28 -> {29};
29 -> {30};
30 -> {31};
31 -> {32};
32 -> {33};
}
@@ -9,7 +9,15 @@ FILE: toLocalVariables.kt
CallsInPlace(z, AT_MOST_ONCE)
>
{
[StubStatement]
{
R|kotlin/contracts/contract|(<L> = contract@fun R|kotlin/contracts/ContractBuilder|.<anonymous>(): R|kotlin/Unit| <inline=Inline, kind=UNKNOWN> {
this@R|special/anonymous|.R|kotlin/contracts/ContractBuilder.callsInPlace|<R|kotlin/Unit|>(R|<local>/x|, Q|kotlin/contracts/InvocationKind|.R|kotlin/contracts/InvocationKind.AT_MOST_ONCE|)
this@R|special/anonymous|.R|kotlin/contracts/ContractBuilder.callsInPlace|<R|kotlin/Unit|>(R|<local>/y|, Q|kotlin/contracts/InvocationKind|.R|kotlin/contracts/InvocationKind.AT_MOST_ONCE|)
this@R|special/anonymous|.R|kotlin/contracts/ContractBuilder.callsInPlace|<R|kotlin/Unit|>(R|<local>/z|, Q|kotlin/contracts/InvocationKind|.R|kotlin/contracts/InvocationKind.AT_MOST_ONCE|)
}
)
}
when () {
Boolean(true) -> {
R|/bar|(R|<local>/x|)
@@ -0,0 +1,29 @@
FILE: noOptIn.kt
public final fun checkIsString(x: R|kotlin/Any|): R|kotlin/Boolean|
[R|Contract description]
<
Returns(TRUE) -> x is kotlin/String
Returns(FALSE) -> x !is kotlin/String
>
{
{
R|kotlin/contracts/contract|(<L> = contract@fun R|kotlin/contracts/ContractBuilder|.<anonymous>(): R|kotlin/Unit| <inline=Inline, kind=UNKNOWN> {
this@R|special/anonymous|.R|kotlin/contracts/ContractBuilder.returns|(Boolean(true)).R|kotlin/contracts/SimpleEffect.implies|((R|<local>/x| is R|kotlin/String|))
this@R|special/anonymous|.R|kotlin/contracts/ContractBuilder.returns|(Boolean(false)).R|kotlin/contracts/SimpleEffect.implies|((R|<local>/x| !is R|kotlin/String|))
}
)
}
^checkIsString (R|<local>/x| is R|kotlin/String|)
}
public final fun test(x: R|kotlin/Any|): R|kotlin/Unit| {
when () {
R|/checkIsString|(R|<local>/x|) -> {
R|<local>/x|.R|kotlin/String.length|
}
else -> {
R|<local>/x|.<Unresolved name: length>#
}
}
}
@@ -0,0 +1,17 @@
import kotlin.contracts.*
fun checkIsString(x: Any): Boolean {
<!OPT_IN_USAGE_ERROR!>contract<!> {
<!OPT_IN_USAGE_ERROR!>returns<!>(true) <!OPT_IN_USAGE_ERROR!>implies<!> (x is String)
<!OPT_IN_USAGE_ERROR!>returns<!>(false) <!OPT_IN_USAGE_ERROR!>implies<!> (x !is String)
}
return x is String
}
fun test(x: Any) {
if (checkIsString(x)) {
x.length // OK
} else {
x.<!UNRESOLVED_REFERENCE!>length<!> // Error
}
}
@@ -5,7 +5,13 @@ FILE: notNull.kt
Returns(NULL) -> x != null
>
{
[StubStatement]
{
R|kotlin/contracts/contract|(<L> = contract@fun R|kotlin/contracts/ContractBuilder|.<anonymous>(): R|kotlin/Unit| <inline=Inline, kind=UNKNOWN> {
this@R|special/anonymous|.R|kotlin/contracts/ContractBuilder.returns|(Null(null)).R|kotlin/contracts/SimpleEffect.implies|(!=(R|<local>/x|, Null(null)))
}
)
}
when () {
Boolean(true) -> {
throw Q|java/lang|.R|java/lang/IllegalArgumentException.IllegalArgumentException|()
@@ -20,7 +26,13 @@ FILE: notNull.kt
Returns(WILDCARD) -> x != null
>
{
[StubStatement]
{
R|kotlin/contracts/contract|(<L> = contract@fun R|kotlin/contracts/ContractBuilder|.<anonymous>(): R|kotlin/Unit| <inline=Inline, kind=UNKNOWN> {
this@R|special/anonymous|.R|kotlin/contracts/ContractBuilder.returns|().R|kotlin/contracts/SimpleEffect.implies|(!=(R|<local>/x|, Null(null)))
}
)
}
when () {
==(R|<local>/x|, Null(null)) -> {
^bar R|<local>/x|
@@ -35,6 +47,12 @@ FILE: notNull.kt
Returns(NULL) -> x != null
>
{
[StubStatement]
{
R|kotlin/contracts/contract|(<L> = contract@fun R|kotlin/contracts/ContractBuilder|.<anonymous>(): R|kotlin/Unit| <inline=Inline, kind=UNKNOWN> {
this@R|special/anonymous|.R|kotlin/contracts/ContractBuilder.returns|(Null(null)).R|kotlin/contracts/SimpleEffect.implies|(!=(R|<local>/x|, Null(null)))
}
)
}
^baz R|<local>/x|
}
@@ -5,7 +5,13 @@ FILE: propertyGetter.kt
Returns(TRUE) -> this != null
>
{
[StubStatement]
{
R|kotlin/contracts/contract|(<L> = contract@fun R|kotlin/contracts/ContractBuilder|.<anonymous>(): R|kotlin/Unit| <inline=Inline, kind=UNKNOWN> {
this@R|special/anonymous|.R|kotlin/contracts/ContractBuilder.returns|(Boolean(true)).R|kotlin/contracts/SimpleEffect.implies|(!=(this@R|/isNotNull|, Null(null)))
}
)
}
^isNotNull !=(this@R|/isNotNull|, Null(null))
}
@R|kotlin/OptIn|(markerClass = vararg(<getClass>(Q|kotlin/contracts/ExperimentalContracts|))) public final val R|kotlin/Any?|.isNotNull: R|kotlin/Boolean|
@@ -15,6 +21,12 @@ FILE: propertyGetter.kt
Returns(TRUE) -> this != null
>
{
[StubStatement]
{
R|kotlin/contracts/contract|(<L> = contract@fun R|kotlin/contracts/ContractBuilder|.<anonymous>(): R|kotlin/Unit| <inline=Inline, kind=UNKNOWN> {
this@R|special/anonymous|.R|kotlin/contracts/ContractBuilder.returns|(Boolean(true)).R|kotlin/contracts/SimpleEffect.implies|(!=(this@R|/isNotNull|, Null(null)))
}
)
}
^ !=(this@R|/isNotNull|, Null(null))
}
@@ -0,0 +1,31 @@
FILE: redundantConditions.kt
@R|kotlin/OptIn|(markerClass = vararg(<getClass>(Q|kotlin/contracts/ExperimentalContracts|))) public final fun testAlwaysNotNull(x: R|kotlin/String?|): R|kotlin/Any?|
[R|Contract description]
<
Returns(NOT_NULL) -> x is kotlin/String && x != null
>
{
{
R|kotlin/contracts/contract|(<L> = contract@fun R|kotlin/contracts/ContractBuilder|.<anonymous>(): R|kotlin/Unit| <inline=Inline, kind=UNKNOWN> {
this@R|special/anonymous|.R|kotlin/contracts/ContractBuilder.returnsNotNull|().R|kotlin/contracts/SimpleEffect.implies|((R|<local>/x| is R|kotlin/String|) && !=(R|<local>/x|, Null(null)))
}
)
}
^testAlwaysNotNull R|<local>/x|
}
@R|kotlin/OptIn|(markerClass = vararg(<getClass>(Q|kotlin/contracts/ExperimentalContracts|))) public final fun testAlwaysAny(x: R|kotlin/String?|): R|kotlin/Any?|
[R|Contract description]
<
Returns(NOT_NULL) -> x is kotlin/String? || x is kotlin/Any?
>
{
{
R|kotlin/contracts/contract|(<L> = contract@fun R|kotlin/contracts/ContractBuilder|.<anonymous>(): R|kotlin/Unit| <inline=Inline, kind=UNKNOWN> {
this@R|special/anonymous|.R|kotlin/contracts/ContractBuilder.returnsNotNull|().R|kotlin/contracts/SimpleEffect.implies|((R|<local>/x| is R|kotlin/String?|) || (R|<local>/x| is R|kotlin/Any?|))
}
)
}
^testAlwaysAny R|<local>/x|
}
@@ -0,0 +1,20 @@
// !OPT_IN: kotlin.RequiresOptIn
import kotlin.contracts.*
@OptIn(ExperimentalContracts::class)
fun testAlwaysNotNull(x: String?): Any? {
contract {
returnsNotNull() implies (x is String && <!SENSELESS_COMPARISON!>x != null<!>)
}
return x
}
@OptIn(ExperimentalContracts::class)
fun testAlwaysAny(x: String?): Any? {
contract {
returnsNotNull() implies (<!USELESS_IS_CHECK!>x is String?<!> || <!USELESS_IS_CHECK!>x is Any?<!>)
}
return x
}