[FIR-TEST] Add tests for contracts resolve
This commit is contained in:
+88
@@ -0,0 +1,88 @@
|
||||
digraph atLeastOnce_kt {
|
||||
graph [nodesep=3]
|
||||
node [shape=box penwidth=2]
|
||||
edge [penwidth=2]
|
||||
|
||||
subgraph cluster_0 {
|
||||
color=red
|
||||
0 [label="Enter function inlineRun" style="filled" fillcolor=red];
|
||||
2 [label="Function call: R|<local>/block|.R|FakeOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()"];
|
||||
1 [label="Exit function inlineRun" style="filled" fillcolor=red];
|
||||
}
|
||||
0 -> {2};
|
||||
2 -> {1};
|
||||
|
||||
subgraph cluster_1 {
|
||||
color=red
|
||||
3 [label="Enter function myRun" style="filled" fillcolor=red];
|
||||
5 [label="Function call: R|<local>/block|.R|FakeOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()"];
|
||||
4 [label="Exit function myRun" style="filled" fillcolor=red];
|
||||
}
|
||||
3 -> {5};
|
||||
5 -> {4};
|
||||
|
||||
subgraph cluster_2 {
|
||||
color=red
|
||||
6 [label="Enter function test_1" style="filled" fillcolor=red];
|
||||
8 [label="Variable declaration: lval x: R|kotlin/Int|"];
|
||||
9 [label="Postponed enter to lambda"];
|
||||
subgraph cluster_3 {
|
||||
color=blue
|
||||
14 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
|
||||
16 [label="Const: Int(1)"];
|
||||
17 [label="Assignment: R|<local>/x|"];
|
||||
15 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
|
||||
}
|
||||
10 [label="Postponed exit from lambda"];
|
||||
11 [label="Function call: R|/inlineRun|(...)"];
|
||||
12 [label="Access variable R|<local>/x|"];
|
||||
13 [label="Function call: R|<local>/x|.R|kotlin/Int.inc|()"];
|
||||
7 [label="Exit function test_1" style="filled" fillcolor=red];
|
||||
}
|
||||
6 -> {8};
|
||||
8 -> {9};
|
||||
9 -> {14};
|
||||
9 -> {10} [color=red];
|
||||
10 -> {11};
|
||||
11 -> {12};
|
||||
12 -> {13};
|
||||
13 -> {7};
|
||||
14 -> {16};
|
||||
15 -> {14};
|
||||
15 -> {10} [color=green];
|
||||
16 -> {17};
|
||||
17 -> {15};
|
||||
|
||||
subgraph cluster_4 {
|
||||
color=red
|
||||
18 [label="Enter function test_2" style="filled" fillcolor=red];
|
||||
20 [label="Variable declaration: lval x: R|kotlin/Int|"];
|
||||
21 [label="Postponed enter to lambda"];
|
||||
subgraph cluster_5 {
|
||||
color=blue
|
||||
26 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
|
||||
28 [label="Const: Int(1)"];
|
||||
29 [label="Assignment: R|<local>/x|"];
|
||||
27 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
|
||||
}
|
||||
22 [label="Postponed exit from lambda"];
|
||||
23 [label="Function call: R|/myRun|(...)"];
|
||||
24 [label="Access variable R|<local>/x|"];
|
||||
25 [label="Function call: R|<local>/x|.R|kotlin/Int.inc|()"];
|
||||
19 [label="Exit function test_2" style="filled" fillcolor=red];
|
||||
}
|
||||
18 -> {20};
|
||||
20 -> {21};
|
||||
21 -> {26};
|
||||
21 -> {22} [color=red];
|
||||
22 -> {23};
|
||||
23 -> {24};
|
||||
24 -> {25};
|
||||
25 -> {19};
|
||||
26 -> {28};
|
||||
27 -> {26};
|
||||
27 -> {22} [color=green];
|
||||
28 -> {29};
|
||||
29 -> {27};
|
||||
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
// !DUMP_CFG
|
||||
|
||||
import kotlin.contracts.*
|
||||
|
||||
inline fun inlineRun(block: () -> Unit) {
|
||||
contract {
|
||||
callsInPlace(block, InvocationKind.AT_LEAST_ONCE)
|
||||
}
|
||||
block()
|
||||
}
|
||||
|
||||
fun myRun(block: () -> Unit) {
|
||||
contract {
|
||||
callsInPlace(block, InvocationKind.AT_LEAST_ONCE)
|
||||
}
|
||||
block()
|
||||
}
|
||||
|
||||
fun test_1() {
|
||||
val x: Int
|
||||
inlineRun {
|
||||
x = 1
|
||||
}
|
||||
x.inc()
|
||||
}
|
||||
|
||||
fun test_2() {
|
||||
val x: Int
|
||||
myRun {
|
||||
x = 1
|
||||
}
|
||||
x.inc()
|
||||
}
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
FILE: atLeastOnce.kt
|
||||
public final inline fun inlineRun(block: R|() -> kotlin/Unit|): R|kotlin/Unit|
|
||||
[R|Contract description]
|
||||
<
|
||||
CallsInPlace(block, AT_LEAST_ONCE)
|
||||
>
|
||||
{
|
||||
[StubStatement]
|
||||
R|<local>/block|.R|FakeOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()
|
||||
}
|
||||
public final fun myRun(block: R|() -> kotlin/Unit|): R|kotlin/Unit|
|
||||
[R|Contract description]
|
||||
<
|
||||
CallsInPlace(block, AT_LEAST_ONCE)
|
||||
>
|
||||
{
|
||||
[StubStatement]
|
||||
R|<local>/block|.R|FakeOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()
|
||||
}
|
||||
public final fun test_1(): R|kotlin/Unit| {
|
||||
lval x: R|kotlin/Int|
|
||||
R|/inlineRun|(<L> = inlineRun@fun <anonymous>(): R|kotlin/Unit| <kind=AT_LEAST_ONCE> {
|
||||
R|<local>/x| = Int(1)
|
||||
}
|
||||
)
|
||||
R|<local>/x|.R|kotlin/Int.inc|()
|
||||
}
|
||||
public final fun test_2(): R|kotlin/Unit| {
|
||||
lval x: R|kotlin/Int|
|
||||
R|/myRun|(<L> = myRun@fun <anonymous>(): R|kotlin/Unit| <kind=AT_LEAST_ONCE> {
|
||||
R|<local>/x| = Int(1)
|
||||
}
|
||||
)
|
||||
R|<local>/x|.R|kotlin/Int.inc|()
|
||||
}
|
||||
+86
@@ -0,0 +1,86 @@
|
||||
digraph atMostOnce_kt {
|
||||
graph [nodesep=3]
|
||||
node [shape=box penwidth=2]
|
||||
edge [penwidth=2]
|
||||
|
||||
subgraph cluster_0 {
|
||||
color=red
|
||||
0 [label="Enter function inlineRun" style="filled" fillcolor=red];
|
||||
2 [label="Function call: R|<local>/block|.R|FakeOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()"];
|
||||
1 [label="Exit function inlineRun" style="filled" fillcolor=red];
|
||||
}
|
||||
0 -> {2};
|
||||
2 -> {1};
|
||||
|
||||
subgraph cluster_1 {
|
||||
color=red
|
||||
3 [label="Enter function myRun" style="filled" fillcolor=red];
|
||||
5 [label="Function call: R|<local>/block|.R|FakeOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()"];
|
||||
4 [label="Exit function myRun" style="filled" fillcolor=red];
|
||||
}
|
||||
3 -> {5};
|
||||
5 -> {4};
|
||||
|
||||
subgraph cluster_2 {
|
||||
color=red
|
||||
6 [label="Enter function test_1" style="filled" fillcolor=red];
|
||||
8 [label="Variable declaration: lval x: R|kotlin/Int|"];
|
||||
9 [label="Postponed enter to lambda"];
|
||||
subgraph cluster_3 {
|
||||
color=blue
|
||||
14 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
|
||||
16 [label="Const: Int(1)"];
|
||||
17 [label="Assignment: R|<local>/x|"];
|
||||
15 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
|
||||
}
|
||||
10 [label="Postponed exit from lambda"];
|
||||
11 [label="Function call: R|/inlineRun|(...)"];
|
||||
12 [label="Access variable R|<local>/x|"];
|
||||
13 [label="Function call: R|<local>/x|.R|kotlin/Int.inc|()"];
|
||||
7 [label="Exit function test_1" style="filled" fillcolor=red];
|
||||
}
|
||||
6 -> {8};
|
||||
8 -> {9};
|
||||
9 -> {14};
|
||||
9 -> {10} [color=red];
|
||||
10 -> {11};
|
||||
11 -> {12};
|
||||
12 -> {13};
|
||||
13 -> {7};
|
||||
14 -> {15 16};
|
||||
15 -> {10} [color=green];
|
||||
16 -> {17};
|
||||
17 -> {15};
|
||||
|
||||
subgraph cluster_4 {
|
||||
color=red
|
||||
18 [label="Enter function test_2" style="filled" fillcolor=red];
|
||||
20 [label="Variable declaration: lval x: R|kotlin/Int|"];
|
||||
21 [label="Postponed enter to lambda"];
|
||||
subgraph cluster_5 {
|
||||
color=blue
|
||||
26 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
|
||||
28 [label="Const: Int(1)"];
|
||||
29 [label="Assignment: R|<local>/x|"];
|
||||
27 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
|
||||
}
|
||||
22 [label="Postponed exit from lambda"];
|
||||
23 [label="Function call: R|/myRun|(...)"];
|
||||
24 [label="Access variable R|<local>/x|"];
|
||||
25 [label="Function call: R|<local>/x|.R|kotlin/Int.inc|()"];
|
||||
19 [label="Exit function test_2" style="filled" fillcolor=red];
|
||||
}
|
||||
18 -> {20};
|
||||
20 -> {21};
|
||||
21 -> {26};
|
||||
21 -> {22} [color=red];
|
||||
22 -> {23};
|
||||
23 -> {24};
|
||||
24 -> {25};
|
||||
25 -> {19};
|
||||
26 -> {27 28};
|
||||
27 -> {22} [color=green];
|
||||
28 -> {29};
|
||||
29 -> {27};
|
||||
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
// !DUMP_CFG
|
||||
|
||||
import kotlin.contracts.*
|
||||
|
||||
inline fun inlineRun(block: () -> Unit) {
|
||||
contract {
|
||||
callsInPlace(block, InvocationKind.AT_MOST_ONCE)
|
||||
}
|
||||
block()
|
||||
}
|
||||
|
||||
fun myRun(block: () -> Unit) {
|
||||
contract {
|
||||
callsInPlace(block, InvocationKind.AT_MOST_ONCE)
|
||||
}
|
||||
block()
|
||||
}
|
||||
|
||||
fun test_1() {
|
||||
val x: Int
|
||||
inlineRun {
|
||||
x = 1
|
||||
}
|
||||
x.inc()
|
||||
}
|
||||
|
||||
fun test_2() {
|
||||
val x: Int
|
||||
myRun {
|
||||
x = 1
|
||||
}
|
||||
x.inc()
|
||||
}
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
FILE: atMostOnce.kt
|
||||
public final inline fun inlineRun(block: R|() -> kotlin/Unit|): R|kotlin/Unit|
|
||||
[R|Contract description]
|
||||
<
|
||||
CallsInPlace(block, AT_MOST_ONCE)
|
||||
>
|
||||
{
|
||||
[StubStatement]
|
||||
R|<local>/block|.R|FakeOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()
|
||||
}
|
||||
public final fun myRun(block: R|() -> kotlin/Unit|): R|kotlin/Unit|
|
||||
[R|Contract description]
|
||||
<
|
||||
CallsInPlace(block, AT_MOST_ONCE)
|
||||
>
|
||||
{
|
||||
[StubStatement]
|
||||
R|<local>/block|.R|FakeOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()
|
||||
}
|
||||
public final fun test_1(): R|kotlin/Unit| {
|
||||
lval x: R|kotlin/Int|
|
||||
R|/inlineRun|(<L> = inlineRun@fun <anonymous>(): R|kotlin/Unit| <kind=AT_MOST_ONCE> {
|
||||
R|<local>/x| = Int(1)
|
||||
}
|
||||
)
|
||||
R|<local>/x|.R|kotlin/Int.inc|()
|
||||
}
|
||||
public final fun test_2(): R|kotlin/Unit| {
|
||||
lval x: R|kotlin/Int|
|
||||
R|/myRun|(<L> = myRun@fun <anonymous>(): R|kotlin/Unit| <kind=AT_MOST_ONCE> {
|
||||
R|<local>/x| = Int(1)
|
||||
}
|
||||
)
|
||||
R|<local>/x|.R|kotlin/Int.inc|()
|
||||
}
|
||||
+92
@@ -0,0 +1,92 @@
|
||||
digraph exactlyOnce_kt {
|
||||
graph [nodesep=3]
|
||||
node [shape=box penwidth=2]
|
||||
edge [penwidth=2]
|
||||
|
||||
subgraph cluster_0 {
|
||||
color=red
|
||||
0 [label="Enter function inlineRun" style="filled" fillcolor=red];
|
||||
2 [label="Function call: R|<local>/block|.R|FakeOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()"];
|
||||
1 [label="Exit function inlineRun" style="filled" fillcolor=red];
|
||||
}
|
||||
0 -> {2};
|
||||
2 -> {1};
|
||||
|
||||
subgraph cluster_1 {
|
||||
color=red
|
||||
3 [label="Enter function myRun" style="filled" fillcolor=red];
|
||||
5 [label="Function call: R|<local>/block|.R|FakeOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()"];
|
||||
4 [label="Exit function myRun" style="filled" fillcolor=red];
|
||||
}
|
||||
3 -> {5};
|
||||
5 -> {4};
|
||||
|
||||
subgraph cluster_2 {
|
||||
color=red
|
||||
6 [label="Enter function test_1" style="filled" fillcolor=red];
|
||||
8 [label="Variable declaration: lval x: R|kotlin/Int|"];
|
||||
9 [label="Postponed enter to lambda"];
|
||||
subgraph cluster_3 {
|
||||
color=blue
|
||||
15 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
|
||||
17 [label="Const: Int(1)"];
|
||||
18 [label="Assignment: R|<local>/x|"];
|
||||
16 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
|
||||
}
|
||||
12 [label="Call arguments union" style="filled" fillcolor=yellow];
|
||||
10 [label="Postponed exit from lambda"];
|
||||
11 [label="Function call: R|/inlineRun|(...)"];
|
||||
13 [label="Access variable R|<local>/x|"];
|
||||
14 [label="Function call: R|<local>/x|.R|kotlin/Int.inc|()"];
|
||||
7 [label="Exit function test_1" style="filled" fillcolor=red];
|
||||
}
|
||||
6 -> {8};
|
||||
8 -> {9};
|
||||
9 -> {15};
|
||||
9 -> {10} [color=red];
|
||||
10 -> {11} [color=green];
|
||||
11 -> {13};
|
||||
12 -> {11} [color=red];
|
||||
13 -> {14};
|
||||
14 -> {7};
|
||||
15 -> {17};
|
||||
16 -> {10} [color=green];
|
||||
16 -> {12} [color=red];
|
||||
17 -> {18};
|
||||
18 -> {16};
|
||||
|
||||
subgraph cluster_4 {
|
||||
color=red
|
||||
19 [label="Enter function test_2" style="filled" fillcolor=red];
|
||||
21 [label="Variable declaration: lval x: R|kotlin/Int|"];
|
||||
22 [label="Postponed enter to lambda"];
|
||||
subgraph cluster_5 {
|
||||
color=blue
|
||||
28 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
|
||||
30 [label="Const: Int(1)"];
|
||||
31 [label="Assignment: R|<local>/x|"];
|
||||
29 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
|
||||
}
|
||||
25 [label="Call arguments union" style="filled" fillcolor=yellow];
|
||||
23 [label="Postponed exit from lambda"];
|
||||
24 [label="Function call: R|/myRun|(...)"];
|
||||
26 [label="Access variable R|<local>/x|"];
|
||||
27 [label="Function call: R|<local>/x|.R|kotlin/Int.inc|()"];
|
||||
20 [label="Exit function test_2" style="filled" fillcolor=red];
|
||||
}
|
||||
19 -> {21};
|
||||
21 -> {22};
|
||||
22 -> {28};
|
||||
22 -> {23} [color=red];
|
||||
23 -> {24} [color=green];
|
||||
24 -> {26};
|
||||
25 -> {24} [color=red];
|
||||
26 -> {27};
|
||||
27 -> {20};
|
||||
28 -> {30};
|
||||
29 -> {23} [color=green];
|
||||
29 -> {25} [color=red];
|
||||
30 -> {31};
|
||||
31 -> {29};
|
||||
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
// !DUMP_CFG
|
||||
|
||||
import kotlin.contracts.*
|
||||
|
||||
inline fun inlineRun(block: () -> Unit) {
|
||||
contract {
|
||||
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||||
}
|
||||
block()
|
||||
}
|
||||
|
||||
fun myRun(block: () -> Unit) {
|
||||
contract {
|
||||
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||||
}
|
||||
block()
|
||||
}
|
||||
|
||||
fun test_1() {
|
||||
val x: Int
|
||||
inlineRun {
|
||||
x = 1
|
||||
}
|
||||
x.inc()
|
||||
}
|
||||
|
||||
fun test_2() {
|
||||
val x: Int
|
||||
myRun {
|
||||
x = 1
|
||||
}
|
||||
x.inc()
|
||||
}
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
FILE: exactlyOnce.kt
|
||||
public final inline fun inlineRun(block: R|() -> kotlin/Unit|): R|kotlin/Unit|
|
||||
[R|Contract description]
|
||||
<
|
||||
CallsInPlace(block, EXACTLY_ONCE)
|
||||
>
|
||||
{
|
||||
[StubStatement]
|
||||
R|<local>/block|.R|FakeOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()
|
||||
}
|
||||
public final fun myRun(block: R|() -> kotlin/Unit|): R|kotlin/Unit|
|
||||
[R|Contract description]
|
||||
<
|
||||
CallsInPlace(block, EXACTLY_ONCE)
|
||||
>
|
||||
{
|
||||
[StubStatement]
|
||||
R|<local>/block|.R|FakeOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()
|
||||
}
|
||||
public final fun test_1(): R|kotlin/Unit| {
|
||||
lval x: R|kotlin/Int|
|
||||
R|/inlineRun|(<L> = inlineRun@fun <anonymous>(): R|kotlin/Unit| <kind=EXACTLY_ONCE> {
|
||||
R|<local>/x| = Int(1)
|
||||
}
|
||||
)
|
||||
R|<local>/x|.R|kotlin/Int.inc|()
|
||||
}
|
||||
public final fun test_2(): R|kotlin/Unit| {
|
||||
lval x: R|kotlin/Int|
|
||||
R|/myRun|(<L> = myRun@fun <anonymous>(): R|kotlin/Unit| <kind=EXACTLY_ONCE> {
|
||||
R|<local>/x| = Int(1)
|
||||
}
|
||||
)
|
||||
R|<local>/x|.R|kotlin/Int.inc|()
|
||||
}
|
||||
+88
@@ -0,0 +1,88 @@
|
||||
digraph unknown_kt {
|
||||
graph [nodesep=3]
|
||||
node [shape=box penwidth=2]
|
||||
edge [penwidth=2]
|
||||
|
||||
subgraph cluster_0 {
|
||||
color=red
|
||||
0 [label="Enter function inlineRun" style="filled" fillcolor=red];
|
||||
2 [label="Function call: R|<local>/block|.R|FakeOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()"];
|
||||
1 [label="Exit function inlineRun" style="filled" fillcolor=red];
|
||||
}
|
||||
0 -> {2};
|
||||
2 -> {1};
|
||||
|
||||
subgraph cluster_1 {
|
||||
color=red
|
||||
3 [label="Enter function myRun" style="filled" fillcolor=red];
|
||||
5 [label="Function call: R|<local>/block|.R|FakeOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()"];
|
||||
4 [label="Exit function myRun" style="filled" fillcolor=red];
|
||||
}
|
||||
3 -> {5};
|
||||
5 -> {4};
|
||||
|
||||
subgraph cluster_2 {
|
||||
color=red
|
||||
6 [label="Enter function test_1" style="filled" fillcolor=red];
|
||||
8 [label="Variable declaration: lval x: R|kotlin/Int|"];
|
||||
9 [label="Postponed enter to lambda"];
|
||||
subgraph cluster_3 {
|
||||
color=blue
|
||||
14 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
|
||||
16 [label="Const: Int(1)"];
|
||||
17 [label="Assignment: R|<local>/x|"];
|
||||
15 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
|
||||
}
|
||||
10 [label="Postponed exit from lambda"];
|
||||
11 [label="Function call: R|/inlineRun|(...)"];
|
||||
12 [label="Access variable R|<local>/x|"];
|
||||
13 [label="Function call: R|<local>/x|.R|kotlin/Int.inc|()"];
|
||||
7 [label="Exit function test_1" style="filled" fillcolor=red];
|
||||
}
|
||||
6 -> {8};
|
||||
8 -> {9};
|
||||
9 -> {14};
|
||||
9 -> {10} [color=red];
|
||||
10 -> {11};
|
||||
11 -> {12};
|
||||
12 -> {13};
|
||||
13 -> {7};
|
||||
14 -> {15 16};
|
||||
15 -> {14};
|
||||
15 -> {10} [color=green];
|
||||
16 -> {17};
|
||||
17 -> {15};
|
||||
|
||||
subgraph cluster_4 {
|
||||
color=red
|
||||
18 [label="Enter function test_2" style="filled" fillcolor=red];
|
||||
20 [label="Variable declaration: lval x: R|kotlin/Int|"];
|
||||
21 [label="Postponed enter to lambda"];
|
||||
subgraph cluster_5 {
|
||||
color=blue
|
||||
26 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
|
||||
28 [label="Const: Int(1)"];
|
||||
29 [label="Assignment: R|<local>/x|"];
|
||||
27 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
|
||||
}
|
||||
22 [label="Postponed exit from lambda"];
|
||||
23 [label="Function call: R|/myRun|(...)"];
|
||||
24 [label="Access variable R|<local>/x|"];
|
||||
25 [label="Function call: R|<local>/x|.R|kotlin/Int.inc|()"];
|
||||
19 [label="Exit function test_2" style="filled" fillcolor=red];
|
||||
}
|
||||
18 -> {20};
|
||||
20 -> {21};
|
||||
21 -> {26};
|
||||
21 -> {22} [color=red];
|
||||
22 -> {23};
|
||||
23 -> {24};
|
||||
24 -> {25};
|
||||
25 -> {19};
|
||||
26 -> {27 28};
|
||||
27 -> {26};
|
||||
27 -> {22} [color=green];
|
||||
28 -> {29};
|
||||
29 -> {27};
|
||||
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
// !DUMP_CFG
|
||||
|
||||
import kotlin.contracts.*
|
||||
|
||||
inline fun inlineRun(block: () -> Unit) {
|
||||
contract {
|
||||
callsInPlace(block, InvocationKind.UNKNOWN)
|
||||
}
|
||||
block()
|
||||
}
|
||||
|
||||
fun myRun(block: () -> Unit) {
|
||||
contract {
|
||||
callsInPlace(block, InvocationKind.UNKNOWN)
|
||||
}
|
||||
block()
|
||||
}
|
||||
|
||||
fun test_1() {
|
||||
val x: Int
|
||||
inlineRun {
|
||||
x = 1
|
||||
}
|
||||
x.inc()
|
||||
}
|
||||
|
||||
fun test_2() {
|
||||
val x: Int
|
||||
myRun {
|
||||
x = 1
|
||||
}
|
||||
x.inc()
|
||||
}
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
FILE: unknown.kt
|
||||
public final inline fun inlineRun(block: R|() -> kotlin/Unit|): R|kotlin/Unit|
|
||||
[R|Contract description]
|
||||
<
|
||||
CallsInPlace(block, UNKNOWN)
|
||||
>
|
||||
{
|
||||
[StubStatement]
|
||||
R|<local>/block|.R|FakeOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()
|
||||
}
|
||||
public final fun myRun(block: R|() -> kotlin/Unit|): R|kotlin/Unit|
|
||||
[R|Contract description]
|
||||
<
|
||||
CallsInPlace(block, UNKNOWN)
|
||||
>
|
||||
{
|
||||
[StubStatement]
|
||||
R|<local>/block|.R|FakeOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()
|
||||
}
|
||||
public final fun test_1(): R|kotlin/Unit| {
|
||||
lval x: R|kotlin/Int|
|
||||
R|/inlineRun|(<L> = inlineRun@fun <anonymous>(): R|kotlin/Unit| <kind=UNKNOWN> {
|
||||
R|<local>/x| = Int(1)
|
||||
}
|
||||
)
|
||||
R|<local>/x|.R|kotlin/Int.inc|()
|
||||
}
|
||||
public final fun test_2(): R|kotlin/Unit| {
|
||||
lval x: R|kotlin/Int|
|
||||
R|/myRun|(<L> = myRun@fun <anonymous>(): R|kotlin/Unit| <kind=UNKNOWN> {
|
||||
R|<local>/x| = Int(1)
|
||||
}
|
||||
)
|
||||
R|<local>/x|.R|kotlin/Int.inc|()
|
||||
}
|
||||
+69
@@ -0,0 +1,69 @@
|
||||
import kotlin.contracts.*
|
||||
|
||||
fun myRequire(b: Boolean) {
|
||||
contract {
|
||||
returns() implies (b)
|
||||
}
|
||||
if (!b) throw IllegalStateException()
|
||||
}
|
||||
|
||||
fun myRequireAnd(b1: Boolean, b2: Boolean) {
|
||||
contract {
|
||||
returns() implies (b1 && b2)
|
||||
}
|
||||
if (!(b1 && b2)) throw IllegalStateException()
|
||||
}
|
||||
|
||||
fun myRequireOr(b1: Boolean, b2: Boolean) {
|
||||
contract {
|
||||
returns() implies (b1 || b2)
|
||||
}
|
||||
if (!(b1 || b2)) throw IllegalStateException()
|
||||
}
|
||||
|
||||
fun myRequireNot(b: Boolean) {
|
||||
contract {
|
||||
returns() implies (!b)
|
||||
}
|
||||
if (b) throw IllegalStateException()
|
||||
}
|
||||
|
||||
// ----------------------------------------------------
|
||||
|
||||
interface A {
|
||||
fun foo()
|
||||
}
|
||||
|
||||
interface B : A {
|
||||
fun bar()
|
||||
}
|
||||
|
||||
interface C : A {
|
||||
fun baz()
|
||||
}
|
||||
|
||||
// ----------------------------------------------------
|
||||
|
||||
fun test_1(x: Any) {
|
||||
myRequire(x is A)
|
||||
x.foo()
|
||||
}
|
||||
|
||||
fun test_2(x: Any) {
|
||||
myRequireAnd(x is B, x is C)
|
||||
x.foo()
|
||||
x.bar()
|
||||
x.baz()
|
||||
}
|
||||
|
||||
fun test_3(x: Any) {
|
||||
myRequireOr(x is B, x is C)
|
||||
x.foo() // OK
|
||||
x.<!UNRESOLVED_REFERENCE!>bar<!>() // Error
|
||||
x.<!UNRESOLVED_REFERENCE!>baz<!>() // Error
|
||||
}
|
||||
|
||||
fun test_4(x: Any) {
|
||||
myRequireNot(x !is A)
|
||||
x.foo()
|
||||
}
|
||||
+89
@@ -0,0 +1,89 @@
|
||||
FILE: booleanOperators.kt
|
||||
public final fun myRequire(b: R|kotlin/Boolean|): R|kotlin/Unit|
|
||||
[R|Contract description]
|
||||
<
|
||||
Returns(WILDCARD) -> b
|
||||
>
|
||||
{
|
||||
[StubStatement]
|
||||
when () {
|
||||
R|<local>/b|.R|kotlin/Boolean.not|() -> {
|
||||
throw R|java/lang/IllegalStateException.IllegalStateException|()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
public final fun myRequireAnd(b1: R|kotlin/Boolean|, b2: R|kotlin/Boolean|): R|kotlin/Unit|
|
||||
[R|Contract description]
|
||||
<
|
||||
Returns(WILDCARD) -> (b1) && (b2)
|
||||
>
|
||||
{
|
||||
[StubStatement]
|
||||
when () {
|
||||
R|<local>/b1| && R|<local>/b2|.R|kotlin/Boolean.not|() -> {
|
||||
throw R|java/lang/IllegalStateException.IllegalStateException|()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
public final fun myRequireOr(b1: R|kotlin/Boolean|, b2: R|kotlin/Boolean|): R|kotlin/Unit|
|
||||
[R|Contract description]
|
||||
<
|
||||
Returns(WILDCARD) -> (b1) || (b2)
|
||||
>
|
||||
{
|
||||
[StubStatement]
|
||||
when () {
|
||||
R|<local>/b1| || R|<local>/b2|.R|kotlin/Boolean.not|() -> {
|
||||
throw R|java/lang/IllegalStateException.IllegalStateException|()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
public final fun myRequireNot(b: R|kotlin/Boolean|): R|kotlin/Unit|
|
||||
[R|Contract description]
|
||||
<
|
||||
Returns(WILDCARD) -> (!)b
|
||||
>
|
||||
{
|
||||
[StubStatement]
|
||||
when () {
|
||||
R|<local>/b| -> {
|
||||
throw R|java/lang/IllegalStateException.IllegalStateException|()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
public abstract interface A : R|kotlin/Any| {
|
||||
public abstract fun foo(): R|kotlin/Unit|
|
||||
|
||||
}
|
||||
public abstract interface B : R|A| {
|
||||
public abstract fun bar(): R|kotlin/Unit|
|
||||
|
||||
}
|
||||
public abstract interface C : R|A| {
|
||||
public abstract fun baz(): R|kotlin/Unit|
|
||||
|
||||
}
|
||||
public final fun test_1(x: R|kotlin/Any|): R|kotlin/Unit| {
|
||||
R|/myRequire|((R|<local>/x| is R|A|))
|
||||
R|<local>/x|.R|/A.foo|()
|
||||
}
|
||||
public final fun test_2(x: R|kotlin/Any|): R|kotlin/Unit| {
|
||||
R|/myRequireAnd|((R|<local>/x| is R|B|), (R|<local>/x| is R|C|))
|
||||
R|<local>/x|.R|/A.foo|()
|
||||
R|<local>/x|.R|/B.bar|()
|
||||
R|<local>/x|.R|/C.baz|()
|
||||
}
|
||||
public final fun test_3(x: R|kotlin/Any|): R|kotlin/Unit| {
|
||||
R|/myRequireOr|((R|<local>/x| is R|B|), (R|<local>/x| is R|C|))
|
||||
R|<local>/x|.R|/A.foo|()
|
||||
R|<local>/x|.<Unresolved name: bar>#()
|
||||
R|<local>/x|.<Unresolved name: baz>#()
|
||||
}
|
||||
public final fun test_4(x: R|kotlin/Any|): R|kotlin/Unit| {
|
||||
R|/myRequireNot|((R|<local>/x| !is R|A|))
|
||||
R|<local>/x|.R|/A.foo|()
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
import kotlin.contracts.*
|
||||
|
||||
fun checkNotNull(x: Any?) {
|
||||
contract {
|
||||
returns(true) implies (x != null)
|
||||
returns(false) implies (x == null)
|
||||
}
|
||||
return x != null
|
||||
}
|
||||
|
||||
fun trickyRequireNotNull(x: Any?) {
|
||||
contract {
|
||||
returns() implies (!(x == null))
|
||||
}
|
||||
if (x == null) {
|
||||
throw IllegalStateException()
|
||||
}
|
||||
}
|
||||
|
||||
fun test_1(x: String?) {
|
||||
if (checkNotNull(x)) {
|
||||
x.length // OK
|
||||
} else {
|
||||
x.<!INAPPLICABLE_CANDIDATE!>length<!> // Error
|
||||
}
|
||||
}
|
||||
|
||||
fun test_2(x: String?) {
|
||||
trickyRequireNotNull(x)
|
||||
x.length
|
||||
}
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
FILE: eqNotEq.kt
|
||||
public final fun checkNotNull(x: R|kotlin/Any?|): R|kotlin/Unit|
|
||||
[R|Contract description]
|
||||
<
|
||||
Returns(TRUE) -> x != null
|
||||
Returns(FALSE) -> x == null
|
||||
>
|
||||
{
|
||||
[StubStatement]
|
||||
^checkNotNull !=(R|<local>/x|, Null(null))
|
||||
}
|
||||
public final fun trickyRequireNotNull(x: R|kotlin/Any?|): R|kotlin/Unit|
|
||||
[R|Contract description]
|
||||
<
|
||||
Returns(WILDCARD) -> !x == null
|
||||
>
|
||||
{
|
||||
[StubStatement]
|
||||
when () {
|
||||
==(R|<local>/x|, Null(null)) -> {
|
||||
throw R|java/lang/IllegalStateException.IllegalStateException|()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
public final fun test_1(x: R|kotlin/String?|): R|kotlin/Unit| {
|
||||
when () {
|
||||
R|/checkNotNull|(R|<local>/x|) -> {
|
||||
R|<local>/x|.R|kotlin/String.length|
|
||||
}
|
||||
else -> {
|
||||
R|<local>/x|.<Inapplicable(WRONG_RECEIVER): [kotlin/String.length]>#
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
public final fun test_2(x: R|kotlin/String?|): R|kotlin/Unit| {
|
||||
R|/trickyRequireNotNull|(R|<local>/x|)
|
||||
R|<local>/x|.R|kotlin/String.length|
|
||||
}
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
import kotlin.contracts.*
|
||||
|
||||
interface A
|
||||
|
||||
fun A.foo() {}
|
||||
|
||||
fun Any?.myRequireNotNull() {
|
||||
contract {
|
||||
returns() implies (this@myRequireNotNull != null)
|
||||
}
|
||||
if (this == null) throw IllegalStateException()
|
||||
}
|
||||
|
||||
fun test_1(x: A?) {
|
||||
x.myRequireNotNull()
|
||||
x.foo()
|
||||
}
|
||||
|
||||
fun test_2(x: A?) {
|
||||
x.myRequireNotNull()
|
||||
with(x) {
|
||||
foo()
|
||||
}
|
||||
}
|
||||
|
||||
fun test_3(x: A?) {
|
||||
with(x) {
|
||||
myRequireNotNull()
|
||||
}
|
||||
x.<!INAPPLICABLE_CANDIDATE!>foo<!>()
|
||||
}
|
||||
|
||||
fun test_4(x: A?) {
|
||||
with(x) {
|
||||
myRequireNotNull()
|
||||
foo()
|
||||
}
|
||||
}
|
||||
|
||||
fun A?.test_5() {
|
||||
myRequireNotNull()
|
||||
foo()
|
||||
}
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
FILE: receivers.kt
|
||||
public abstract interface A : R|kotlin/Any| {
|
||||
}
|
||||
public final fun R|A|.foo(): R|kotlin/Unit| {
|
||||
}
|
||||
public final fun R|kotlin/Any?|.myRequireNotNull(): R|kotlin/Unit|
|
||||
[R|Contract description]
|
||||
<
|
||||
Returns(WILDCARD) -> this != null
|
||||
>
|
||||
{
|
||||
[StubStatement]
|
||||
when () {
|
||||
==(this@R|/myRequireNotNull|, Null(null)) -> {
|
||||
throw R|java/lang/IllegalStateException.IllegalStateException|()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
public final fun test_1(x: R|A?|): R|kotlin/Unit| {
|
||||
R|<local>/x|.R|/myRequireNotNull|()
|
||||
R|<local>/x|.R|/foo|()
|
||||
}
|
||||
public final fun test_2(x: R|A?|): R|kotlin/Unit| {
|
||||
R|<local>/x|.R|/myRequireNotNull|()
|
||||
R|kotlin/with|<R|A|, R|kotlin/Unit|>(R|<local>/x|, <L> = with@fun R|A|.<anonymous>(): R|kotlin/Unit| <kind=EXACTLY_ONCE> {
|
||||
this@R|special/anonymous|.R|/foo|()
|
||||
}
|
||||
)
|
||||
}
|
||||
public final fun test_3(x: R|A?|): R|kotlin/Unit| {
|
||||
R|kotlin/with|<R|A?|, R|kotlin/Unit|>(R|<local>/x|, <L> = with@fun R|A?|.<anonymous>(): R|kotlin/Unit| <kind=EXACTLY_ONCE> {
|
||||
this@R|special/anonymous|.R|/myRequireNotNull|()
|
||||
}
|
||||
)
|
||||
R|<local>/x|.<Inapplicable(WRONG_RECEIVER): [/foo]>#()
|
||||
}
|
||||
public final fun test_4(x: R|A?|): R|kotlin/Unit| {
|
||||
R|kotlin/with|<R|A?|, R|kotlin/Unit|>(R|<local>/x|, <L> = with@fun R|A?|.<anonymous>(): R|kotlin/Unit| <kind=EXACTLY_ONCE> {
|
||||
this@R|special/anonymous|.R|/myRequireNotNull|()
|
||||
this@R|special/anonymous|.R|/foo|()
|
||||
}
|
||||
)
|
||||
}
|
||||
public final fun R|A?|.test_5(): R|kotlin/Unit| {
|
||||
this@R|/test_5|.R|/myRequireNotNull|()
|
||||
this@R|/test_5|.R|/foo|()
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
import kotlin.contracts.*
|
||||
|
||||
fun checkIsString(x: Any) {
|
||||
contract {
|
||||
returns(true) implies (x is String)
|
||||
returns(false) implies (x !is String)
|
||||
}
|
||||
return x is String
|
||||
}
|
||||
|
||||
fun test(x: Any) {
|
||||
if (checkIsString(x)) {
|
||||
x.length // OK
|
||||
} else {
|
||||
x.<!UNRESOLVED_REFERENCE!>length<!> // Error
|
||||
}
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
FILE: typePredicate.kt
|
||||
public final fun checkIsString(x: R|kotlin/Any|): R|kotlin/Unit|
|
||||
[R|Contract description]
|
||||
<
|
||||
Returns(TRUE) -> x is kotlin/String
|
||||
Returns(FALSE) -> x !is kotlin/String
|
||||
>
|
||||
{
|
||||
[StubStatement]
|
||||
^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>#
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+92
@@ -513,6 +513,98 @@ public class FirDiagnosticsWithStdlibTestGenerated extends AbstractFirDiagnostic
|
||||
runTest("compiler/fir/analysis-tests/testData/resolveWithStdlib/contracts/fromLibrary/notIsNullOrEmpty.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/fir/analysis-tests/testData/resolveWithStdlib/contracts/fromSource")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class FromSource extends AbstractFirDiagnosticsWithStdlibTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInFromSource() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolveWithStdlib/contracts/fromSource"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/fir/analysis-tests/testData/resolveWithStdlib/contracts/fromSource/good")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class Good extends AbstractFirDiagnosticsWithStdlibTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInGood() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolveWithStdlib/contracts/fromSource/good"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/fir/analysis-tests/testData/resolveWithStdlib/contracts/fromSource/good/callsInPlace")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class CallsInPlace extends AbstractFirDiagnosticsWithStdlibTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInCallsInPlace() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolveWithStdlib/contracts/fromSource/good/callsInPlace"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
|
||||
}
|
||||
|
||||
@TestMetadata("atLeastOnce.kt")
|
||||
public void testAtLeastOnce() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/resolveWithStdlib/contracts/fromSource/good/callsInPlace/atLeastOnce.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("atMostOnce.kt")
|
||||
public void testAtMostOnce() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/resolveWithStdlib/contracts/fromSource/good/callsInPlace/atMostOnce.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("exactlyOnce.kt")
|
||||
public void testExactlyOnce() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/resolveWithStdlib/contracts/fromSource/good/callsInPlace/exactlyOnce.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("unknown.kt")
|
||||
public void testUnknown() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/resolveWithStdlib/contracts/fromSource/good/callsInPlace/unknown.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/fir/analysis-tests/testData/resolveWithStdlib/contracts/fromSource/good/returnsImplies")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class ReturnsImplies extends AbstractFirDiagnosticsWithStdlibTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInReturnsImplies() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolveWithStdlib/contracts/fromSource/good/returnsImplies"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
|
||||
}
|
||||
|
||||
@TestMetadata("booleanOperators.kt")
|
||||
public void testBooleanOperators() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/resolveWithStdlib/contracts/fromSource/good/returnsImplies/booleanOperators.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("eqNotEq.kt")
|
||||
public void testEqNotEq() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/resolveWithStdlib/contracts/fromSource/good/returnsImplies/eqNotEq.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("receivers.kt")
|
||||
public void testReceivers() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/resolveWithStdlib/contracts/fromSource/good/returnsImplies/receivers.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("typePredicate.kt")
|
||||
public void testTypePredicate() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/resolveWithStdlib/contracts/fromSource/good/returnsImplies/typePredicate.kt");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/fir/analysis-tests/testData/resolveWithStdlib/delegates")
|
||||
|
||||
Reference in New Issue
Block a user