[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
@@ -5193,6 +5193,12 @@ public class DiagnosisCompilerFirTestdataTestGenerated extends AbstractDiagnosis
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolveWithStdlib/contracts/fromSource/bad"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
}
@Test
@TestMetadata("noOptIn.kt")
public void testNoOptIn() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolveWithStdlib/contracts/fromSource/bad/noOptIn.kt");
}
@Nested
@TestMetadata("compiler/fir/analysis-tests/testData/resolveWithStdlib/contracts/fromSource/bad/callsInPlace")
@TestDataPath("$PROJECT_ROOT")
@@ -5247,6 +5253,12 @@ public class DiagnosisCompilerFirTestdataTestGenerated extends AbstractDiagnosis
public void testPropertyGetter() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolveWithStdlib/contracts/fromSource/bad/returnsImplies/propertyGetter.kt");
}
@Test
@TestMetadata("redundantConditions.kt")
public void testRedundantConditions() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolveWithStdlib/contracts/fromSource/bad/returnsImplies/redundantConditions.kt");
}
}
}
File diff suppressed because it is too large Load Diff
@@ -5,7 +5,13 @@ FILE: flowFromInplaceLambda.kt
CallsInPlace(x, UNKNOWN)
>
{
[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|T|>(R|<local>/x|, Q|kotlin/contracts/InvocationKind|.R|kotlin/contracts/InvocationKind.UNKNOWN|)
}
)
}
^unknown R|<local>/x|.R|SubstitutionOverride<kotlin/Function0.invoke: R|T|>|()
}
public final fun <T> atLeastOnce(x: R|() -> T|): R|T|
@@ -14,7 +20,13 @@ FILE: flowFromInplaceLambda.kt
CallsInPlace(x, AT_LEAST_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|T|>(R|<local>/x|, Q|kotlin/contracts/InvocationKind|.R|kotlin/contracts/InvocationKind.AT_LEAST_ONCE|)
}
)
}
^atLeastOnce R|<local>/x|.R|SubstitutionOverride<kotlin/Function0.invoke: R|T|>|()
}
public final fun <T> exactlyOnce(x: R|() -> T|): R|T|
@@ -23,7 +35,13 @@ FILE: flowFromInplaceLambda.kt
CallsInPlace(x, EXACTLY_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|T|>(R|<local>/x|, Q|kotlin/contracts/InvocationKind|.R|kotlin/contracts/InvocationKind.EXACTLY_ONCE|)
}
)
}
^exactlyOnce R|<local>/x|.R|SubstitutionOverride<kotlin/Function0.invoke: R|T|>|()
}
public final fun <T> atMostOnce(x: R|() -> T|): R|T|
@@ -32,7 +50,13 @@ FILE: flowFromInplaceLambda.kt
CallsInPlace(x, 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|T|>(R|<local>/x|, Q|kotlin/contracts/InvocationKind|.R|kotlin/contracts/InvocationKind.AT_MOST_ONCE|)
}
)
}
^atMostOnce R|<local>/x|.R|SubstitutionOverride<kotlin/Function0.invoke: R|T|>|()
}
public final fun <T> noContract(x: R|() -> T|): R|T| {
@@ -1,4 +1,5 @@
// !DUMP_CFG
// !OPT_IN: kotlin.contracts.ExperimentalContracts
import kotlin.contracts.*
@@ -9,350 +9,262 @@ digraph flowFromInplaceLambda3_kt {
subgraph cluster_1 {
color=blue
1 [label="Enter block"];
2 [label="Function call: R|<local>/x|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()" style="filled" fillcolor=yellow];
3 [label="Exit block"];
subgraph cluster_2 {
color=blue
2 [label="Enter block"];
3 [label="Exit block"];
}
4 [label="Function call: R|<local>/x|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()" style="filled" fillcolor=yellow];
5 [label="Exit block"];
}
4 [label="Exit function unknown" style="filled" fillcolor=red];
6 [label="Exit function unknown" style="filled" fillcolor=red];
}
0 -> {1};
1 -> {2};
2 -> {3};
3 -> {4};
subgraph cluster_2 {
color=red
5 [label="Enter function atLeastOnce" style="filled" fillcolor=red];
subgraph cluster_3 {
color=blue
6 [label="Enter block"];
7 [label="Function call: R|<local>/x|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()" style="filled" fillcolor=yellow];
8 [label="Exit block"];
}
9 [label="Exit function atLeastOnce" style="filled" fillcolor=red];
}
4 -> {5};
5 -> {6};
6 -> {7};
7 -> {8};
8 -> {9};
subgraph cluster_4 {
subgraph cluster_3 {
color=red
10 [label="Enter function exactlyOnce" style="filled" fillcolor=red];
subgraph cluster_5 {
color=blue
11 [label="Enter block"];
12 [label="Function call: R|<local>/x|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()" style="filled" fillcolor=yellow];
13 [label="Exit block"];
}
14 [label="Exit function exactlyOnce" style="filled" fillcolor=red];
}
10 -> {11};
11 -> {12};
12 -> {13};
13 -> {14};
subgraph cluster_6 {
color=red
15 [label="Enter function atMostOnce" style="filled" fillcolor=red];
subgraph cluster_7 {
15 [label="Enter function atLeastOnce" style="filled" fillcolor=red];
subgraph cluster_4 {
color=blue
16 [label="Enter block"];
17 [label="Exit block"];
subgraph cluster_5 {
color=blue
17 [label="Enter block"];
18 [label="Exit block"];
}
19 [label="Function call: R|<local>/x|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()" style="filled" fillcolor=yellow];
20 [label="Exit block"];
}
18 [label="Exit function atMostOnce" style="filled" fillcolor=red];
21 [label="Exit function atLeastOnce" style="filled" fillcolor=red];
}
15 -> {16};
16 -> {17};
17 -> {18};
subgraph cluster_8 {
color=red
19 [label="Enter function test1" style="filled" fillcolor=red];
subgraph cluster_9 {
color=blue
20 [label="Enter block"];
21 [label="Variable declaration: lvar x: R|kotlin/Any?|"];
22 [label="Const: String()"];
23 [label="Assignment: R|<local>/x|"];
24 [label="Access variable R|<local>/x|"];
25 [label="Smart cast: R|<local>/x|"];
26 [label="Access variable R|kotlin/String.length|"];
27 [label="Postponed enter to lambda"];
subgraph cluster_10 {
color=blue
38 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
subgraph cluster_11 {
color=blue
39 [label="Enter block"];
40 [label="Const: Int(1)"];
41 [label="Assignment: R|<local>/x|"];
42 [label="Exit block"];
}
43 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
}
28 [label="Postponed exit from lambda"];
29 [label="Function call: R|/unknown|(...)" style="filled" fillcolor=yellow];
30 [label="Access variable R|<local>/x|"];
31 [label="Smart cast: R|<local>/x|"];
32 [label="Access variable <Unresolved name: length>#"];
33 [label="Access variable R|<local>/x|"];
34 [label="Smart cast: R|<local>/x|"];
35 [label="Function call: R|<local>/x|.<Unresolved name: inc>#()" style="filled" fillcolor=yellow];
36 [label="Exit block"];
}
37 [label="Exit function test1" style="filled" fillcolor=red];
}
18 -> {19};
19 -> {20};
20 -> {21};
21 -> {22};
22 -> {23};
23 -> {24};
24 -> {25};
25 -> {26};
26 -> {27};
27 -> {28 38 29};
27 -> {38} [style=dashed];
28 -> {29};
28 -> {27} [color=green style=dashed];
29 -> {30};
subgraph cluster_6 {
color=red
30 [label="Enter function exactlyOnce" style="filled" fillcolor=red];
subgraph cluster_7 {
color=blue
31 [label="Enter block"];
subgraph cluster_8 {
color=blue
32 [label="Enter block"];
33 [label="Exit block"];
}
34 [label="Function call: R|<local>/x|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()" style="filled" fillcolor=yellow];
35 [label="Exit block"];
}
36 [label="Exit function exactlyOnce" style="filled" fillcolor=red];
}
30 -> {31};
31 -> {32};
32 -> {33};
33 -> {34};
34 -> {35};
35 -> {36};
36 -> {37};
38 -> {39};
39 -> {40};
40 -> {41};
41 -> {42};
42 -> {43};
43 -> {28};
subgraph cluster_12 {
subgraph cluster_9 {
color=red
44 [label="Enter function test1m" style="filled" fillcolor=red];
subgraph cluster_13 {
45 [label="Enter function atMostOnce" style="filled" fillcolor=red];
subgraph cluster_10 {
color=blue
45 [label="Enter block"];
46 [label="Variable declaration: lvar x: R|kotlin/Any?|"];
47 [label="Const: String()"];
48 [label="Assignment: R|<local>/x|"];
49 [label="Access variable R|<local>/x|"];
50 [label="Smart cast: R|<local>/x|"];
51 [label="Access variable R|kotlin/String.length|"];
52 [label="Postponed enter to lambda"];
subgraph cluster_14 {
46 [label="Enter block"];
subgraph cluster_11 {
color=blue
60 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
subgraph cluster_15 {
color=blue
61 [label="Enter block"];
62 [label="Const: String()"];
63 [label="Assignment: R|<local>/x|"];
64 [label="Exit block"];
}
65 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
47 [label="Enter block"];
48 [label="Exit block"];
}
53 [label="Postponed exit from lambda"];
54 [label="Function call: R|/unknown|(...)" style="filled" fillcolor=yellow];
55 [label="Access variable R|<local>/x|"];
56 [label="Smart cast: R|<local>/x|"];
57 [label="Access variable R|kotlin/String.length|"];
58 [label="Exit block"];
49 [label="Exit block"];
}
59 [label="Exit function test1m" style="filled" fillcolor=red];
50 [label="Exit function atMostOnce" style="filled" fillcolor=red];
}
44 -> {45};
45 -> {46};
46 -> {47};
47 -> {48};
48 -> {49};
49 -> {50};
50 -> {51};
51 -> {52};
52 -> {53 60 54};
52 -> {60} [style=dashed];
53 -> {54};
53 -> {52} [color=green style=dashed];
54 -> {55};
55 -> {56};
56 -> {57};
57 -> {58};
58 -> {59};
subgraph cluster_12 {
color=red
59 [label="Enter function test1" style="filled" fillcolor=red];
subgraph cluster_13 {
color=blue
60 [label="Enter block"];
61 [label="Variable declaration: lvar x: R|kotlin/Any?|"];
62 [label="Const: String()"];
63 [label="Assignment: R|<local>/x|"];
64 [label="Access variable R|<local>/x|"];
65 [label="Smart cast: R|<local>/x|"];
66 [label="Access variable R|kotlin/String.length|"];
67 [label="Postponed enter to lambda"];
subgraph cluster_14 {
color=blue
78 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
subgraph cluster_15 {
color=blue
79 [label="Enter block"];
80 [label="Const: Int(1)"];
81 [label="Assignment: R|<local>/x|"];
82 [label="Exit block"];
}
83 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
}
68 [label="Postponed exit from lambda"];
69 [label="Function call: R|/unknown|(...)" style="filled" fillcolor=yellow];
70 [label="Access variable R|<local>/x|"];
71 [label="Smart cast: R|<local>/x|"];
72 [label="Access variable <Unresolved name: length>#"];
73 [label="Access variable R|<local>/x|"];
74 [label="Smart cast: R|<local>/x|"];
75 [label="Function call: R|<local>/x|.<Unresolved name: inc>#()" style="filled" fillcolor=yellow];
76 [label="Exit block"];
}
77 [label="Exit function test1" style="filled" fillcolor=red];
}
59 -> {60};
60 -> {61};
61 -> {62};
62 -> {63};
63 -> {64};
64 -> {65};
65 -> {53};
subgraph cluster_16 {
color=red
66 [label="Enter function test2" style="filled" fillcolor=red];
subgraph cluster_17 {
color=blue
67 [label="Enter block"];
68 [label="Variable declaration: lvar x: R|kotlin/Any?|"];
69 [label="Const: String()"];
70 [label="Assignment: R|<local>/x|"];
71 [label="Access variable R|<local>/x|"];
72 [label="Smart cast: R|<local>/x|"];
73 [label="Access variable R|kotlin/String.length|"];
74 [label="Postponed enter to lambda"];
subgraph cluster_18 {
color=blue
85 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
subgraph cluster_19 {
color=blue
86 [label="Enter block"];
87 [label="Const: Int(1)"];
88 [label="Assignment: R|<local>/x|"];
89 [label="Exit block"];
}
90 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
}
75 [label="Postponed exit from lambda"];
76 [label="Function call: R|/atLeastOnce|(...)" style="filled" fillcolor=yellow];
77 [label="Access variable R|<local>/x|"];
78 [label="Smart cast: R|<local>/x|"];
79 [label="Access variable <Unresolved name: length>#"];
80 [label="Access variable R|<local>/x|"];
81 [label="Smart cast: R|<local>/x|"];
82 [label="Function call: R|<local>/x|.R|kotlin/Int.inc|()" style="filled" fillcolor=yellow];
83 [label="Exit block"];
}
84 [label="Exit function test2" style="filled" fillcolor=red];
}
65 -> {66};
66 -> {67};
67 -> {68};
67 -> {68 78 69};
67 -> {78} [style=dashed];
68 -> {69};
68 -> {67} [color=green style=dashed];
69 -> {70};
70 -> {71};
71 -> {72};
72 -> {73};
73 -> {74};
74 -> {85 76};
74 -> {75} [style=dotted];
74 -> {85} [style=dashed];
74 -> {75};
75 -> {76};
75 -> {74} [color=green style=dashed];
76 -> {77};
77 -> {78};
78 -> {79};
79 -> {80};
80 -> {81};
81 -> {82};
82 -> {83};
83 -> {84};
83 -> {68};
subgraph cluster_16 {
color=red
84 [label="Enter function test1m" style="filled" fillcolor=red];
subgraph cluster_17 {
color=blue
85 [label="Enter block"];
86 [label="Variable declaration: lvar x: R|kotlin/Any?|"];
87 [label="Const: String()"];
88 [label="Assignment: R|<local>/x|"];
89 [label="Access variable R|<local>/x|"];
90 [label="Smart cast: R|<local>/x|"];
91 [label="Access variable R|kotlin/String.length|"];
92 [label="Postponed enter to lambda"];
subgraph cluster_18 {
color=blue
100 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
subgraph cluster_19 {
color=blue
101 [label="Enter block"];
102 [label="Const: String()"];
103 [label="Assignment: R|<local>/x|"];
104 [label="Exit block"];
}
105 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
}
93 [label="Postponed exit from lambda"];
94 [label="Function call: R|/unknown|(...)" style="filled" fillcolor=yellow];
95 [label="Access variable R|<local>/x|"];
96 [label="Smart cast: R|<local>/x|"];
97 [label="Access variable R|kotlin/String.length|"];
98 [label="Exit block"];
}
99 [label="Exit function test1m" style="filled" fillcolor=red];
}
84 -> {85};
85 -> {86};
86 -> {87};
87 -> {88};
88 -> {89};
89 -> {90};
90 -> {75};
subgraph cluster_20 {
color=red
91 [label="Enter function test3" style="filled" fillcolor=red];
subgraph cluster_21 {
color=blue
92 [label="Enter block"];
93 [label="Variable declaration: lvar x: R|kotlin/Any?|"];
94 [label="Const: String()"];
95 [label="Assignment: R|<local>/x|"];
96 [label="Access variable R|<local>/x|"];
97 [label="Smart cast: R|<local>/x|"];
98 [label="Access variable R|kotlin/String.length|"];
99 [label="Postponed enter to lambda"];
subgraph cluster_22 {
color=blue
110 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
subgraph cluster_23 {
color=blue
111 [label="Enter block"];
112 [label="Const: Int(1)"];
113 [label="Assignment: R|<local>/x|"];
114 [label="Exit block"];
}
115 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
}
100 [label="Postponed exit from lambda"];
101 [label="Function call: R|/exactlyOnce|(...)" style="filled" fillcolor=yellow];
102 [label="Access variable R|<local>/x|"];
103 [label="Smart cast: R|<local>/x|"];
104 [label="Access variable <Unresolved name: length>#"];
105 [label="Access variable R|<local>/x|"];
106 [label="Smart cast: R|<local>/x|"];
107 [label="Function call: R|<local>/x|.R|kotlin/Int.inc|()" style="filled" fillcolor=yellow];
108 [label="Exit block"];
}
109 [label="Exit function test3" style="filled" fillcolor=red];
}
90 -> {91};
91 -> {92};
92 -> {93};
92 -> {93 100 94};
92 -> {100} [style=dashed];
93 -> {94};
93 -> {92} [color=green style=dashed];
94 -> {95};
95 -> {96};
96 -> {97};
97 -> {98};
98 -> {99};
99 -> {110 101};
99 -> {100} [style=dotted];
99 -> {110} [style=dashed];
100 -> {101};
101 -> {102};
102 -> {103};
103 -> {104};
104 -> {105};
105 -> {106};
105 -> {93};
subgraph cluster_20 {
color=red
106 [label="Enter function test2" style="filled" fillcolor=red];
subgraph cluster_21 {
color=blue
107 [label="Enter block"];
108 [label="Variable declaration: lvar x: R|kotlin/Any?|"];
109 [label="Const: String()"];
110 [label="Assignment: R|<local>/x|"];
111 [label="Access variable R|<local>/x|"];
112 [label="Smart cast: R|<local>/x|"];
113 [label="Access variable R|kotlin/String.length|"];
114 [label="Postponed enter to lambda"];
subgraph cluster_22 {
color=blue
125 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
subgraph cluster_23 {
color=blue
126 [label="Enter block"];
127 [label="Const: Int(1)"];
128 [label="Assignment: R|<local>/x|"];
129 [label="Exit block"];
}
130 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
}
115 [label="Postponed exit from lambda"];
116 [label="Function call: R|/atLeastOnce|(...)" style="filled" fillcolor=yellow];
117 [label="Access variable R|<local>/x|"];
118 [label="Smart cast: R|<local>/x|"];
119 [label="Access variable <Unresolved name: length>#"];
120 [label="Access variable R|<local>/x|"];
121 [label="Smart cast: R|<local>/x|"];
122 [label="Function call: R|<local>/x|.R|kotlin/Int.inc|()" style="filled" fillcolor=yellow];
123 [label="Exit block"];
}
124 [label="Exit function test2" style="filled" fillcolor=red];
}
106 -> {107};
107 -> {108};
108 -> {109};
109 -> {110};
110 -> {111};
111 -> {112};
112 -> {113};
113 -> {114};
114 -> {115};
115 -> {100};
subgraph cluster_24 {
color=red
116 [label="Enter function test4" style="filled" fillcolor=red];
subgraph cluster_25 {
color=blue
117 [label="Enter block"];
118 [label="Variable declaration: lvar x: R|kotlin/Any?|"];
119 [label="Const: String()"];
120 [label="Assignment: R|<local>/x|"];
121 [label="Access variable R|<local>/x|"];
122 [label="Smart cast: R|<local>/x|"];
123 [label="Access variable R|kotlin/String.length|"];
124 [label="Postponed enter to lambda"];
subgraph cluster_26 {
color=blue
135 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
subgraph cluster_27 {
color=blue
136 [label="Enter block"];
137 [label="Const: Int(1)"];
138 [label="Assignment: R|<local>/x|"];
139 [label="Exit block"];
}
140 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
}
125 [label="Postponed exit from lambda"];
126 [label="Function call: R|/atMostOnce|(...)" style="filled" fillcolor=yellow];
127 [label="Access variable R|<local>/x|"];
128 [label="Smart cast: R|<local>/x|"];
129 [label="Access variable <Unresolved name: length>#"];
130 [label="Access variable R|<local>/x|"];
131 [label="Smart cast: R|<local>/x|"];
132 [label="Function call: R|<local>/x|.<Unresolved name: inc>#()" style="filled" fillcolor=yellow];
133 [label="Exit block"];
}
134 [label="Exit function test4" style="filled" fillcolor=red];
}
114 -> {125 116};
114 -> {115} [style=dotted];
114 -> {125} [style=dashed];
115 -> {116};
115 -> {114} [color=green style=dashed];
116 -> {117};
117 -> {118};
118 -> {119};
@@ -361,22 +273,138 @@ digraph flowFromInplaceLambda3_kt {
121 -> {122};
122 -> {123};
123 -> {124};
124 -> {125 135 126};
124 -> {135} [style=dashed];
125 -> {126};
126 -> {127};
127 -> {128};
128 -> {129};
129 -> {130};
130 -> {131};
130 -> {115};
subgraph cluster_24 {
color=red
131 [label="Enter function test3" style="filled" fillcolor=red];
subgraph cluster_25 {
color=blue
132 [label="Enter block"];
133 [label="Variable declaration: lvar x: R|kotlin/Any?|"];
134 [label="Const: String()"];
135 [label="Assignment: R|<local>/x|"];
136 [label="Access variable R|<local>/x|"];
137 [label="Smart cast: R|<local>/x|"];
138 [label="Access variable R|kotlin/String.length|"];
139 [label="Postponed enter to lambda"];
subgraph cluster_26 {
color=blue
150 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
subgraph cluster_27 {
color=blue
151 [label="Enter block"];
152 [label="Const: Int(1)"];
153 [label="Assignment: R|<local>/x|"];
154 [label="Exit block"];
}
155 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
}
140 [label="Postponed exit from lambda"];
141 [label="Function call: R|/exactlyOnce|(...)" style="filled" fillcolor=yellow];
142 [label="Access variable R|<local>/x|"];
143 [label="Smart cast: R|<local>/x|"];
144 [label="Access variable <Unresolved name: length>#"];
145 [label="Access variable R|<local>/x|"];
146 [label="Smart cast: R|<local>/x|"];
147 [label="Function call: R|<local>/x|.R|kotlin/Int.inc|()" style="filled" fillcolor=yellow];
148 [label="Exit block"];
}
149 [label="Exit function test3" style="filled" fillcolor=red];
}
131 -> {132};
132 -> {133};
133 -> {134};
134 -> {135};
135 -> {136};
136 -> {137};
137 -> {138};
138 -> {139};
139 -> {140};
140 -> {125};
139 -> {150 141};
139 -> {140} [style=dotted];
139 -> {150} [style=dashed];
140 -> {141};
141 -> {142};
142 -> {143};
143 -> {144};
144 -> {145};
145 -> {146};
146 -> {147};
147 -> {148};
148 -> {149};
150 -> {151};
151 -> {152};
152 -> {153};
153 -> {154};
154 -> {155};
155 -> {140};
subgraph cluster_28 {
color=red
156 [label="Enter function test4" style="filled" fillcolor=red];
subgraph cluster_29 {
color=blue
157 [label="Enter block"];
158 [label="Variable declaration: lvar x: R|kotlin/Any?|"];
159 [label="Const: String()"];
160 [label="Assignment: R|<local>/x|"];
161 [label="Access variable R|<local>/x|"];
162 [label="Smart cast: R|<local>/x|"];
163 [label="Access variable R|kotlin/String.length|"];
164 [label="Postponed enter to lambda"];
subgraph cluster_30 {
color=blue
175 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
subgraph cluster_31 {
color=blue
176 [label="Enter block"];
177 [label="Const: Int(1)"];
178 [label="Assignment: R|<local>/x|"];
179 [label="Exit block"];
}
180 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
}
165 [label="Postponed exit from lambda"];
166 [label="Function call: R|/atMostOnce|(...)" style="filled" fillcolor=yellow];
167 [label="Access variable R|<local>/x|"];
168 [label="Smart cast: R|<local>/x|"];
169 [label="Access variable <Unresolved name: length>#"];
170 [label="Access variable R|<local>/x|"];
171 [label="Smart cast: R|<local>/x|"];
172 [label="Function call: R|<local>/x|.<Unresolved name: inc>#()" style="filled" fillcolor=yellow];
173 [label="Exit block"];
}
174 [label="Exit function test4" style="filled" fillcolor=red];
}
156 -> {157};
157 -> {158};
158 -> {159};
159 -> {160};
160 -> {161};
161 -> {162};
162 -> {163};
163 -> {164};
164 -> {165 175 166};
164 -> {175} [style=dashed];
165 -> {166};
166 -> {167};
167 -> {168};
168 -> {169};
169 -> {170};
170 -> {171};
171 -> {172};
172 -> {173};
173 -> {174};
175 -> {176};
176 -> {177};
177 -> {178};
178 -> {179};
179 -> {180};
180 -> {165};
}
@@ -5,7 +5,13 @@ FILE: flowFromInplaceLambda3.kt
CallsInPlace(x, UNKNOWN)
>
{
[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.UNKNOWN|)
}
)
}
R|<local>/x|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()
}
public final fun atLeastOnce(x: R|() -> kotlin/Unit|): R|kotlin/Unit|
@@ -14,7 +20,13 @@ FILE: flowFromInplaceLambda3.kt
CallsInPlace(x, AT_LEAST_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_LEAST_ONCE|)
}
)
}
R|<local>/x|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()
}
public final fun exactlyOnce(x: R|() -> kotlin/Unit|): R|kotlin/Unit|
@@ -23,7 +35,13 @@ FILE: flowFromInplaceLambda3.kt
CallsInPlace(x, EXACTLY_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.EXACTLY_ONCE|)
}
)
}
R|<local>/x|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()
}
public final fun atMostOnce(x: R|() -> kotlin/Unit|): R|kotlin/Unit|
@@ -32,7 +50,13 @@ FILE: flowFromInplaceLambda3.kt
CallsInPlace(x, 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|)
}
)
}
}
public final fun test1(): R|kotlin/Unit| {
lvar x: R|kotlin/Any?|
@@ -1,4 +1,5 @@
// !DUMP_CFG
// !OPT_IN: kotlin.contracts.ExperimentalContracts
import kotlin.contracts.*
File diff suppressed because it is too large Load Diff
@@ -2,14 +2,21 @@ FILE: flowFromTwoInplaceLambdas.kt
public final fun <T> n(): R|T?| {
^n Null(null)
}
public final fun <T> run2(x: R|() -> T|, y: R|() -> T|): R|kotlin/Unit|
@R|kotlin/OptIn|(markerClass = vararg(<getClass>(Q|kotlin/contracts/ExperimentalContracts|))) public final fun <T> run2(x: R|() -> T|, y: R|() -> T|): R|kotlin/Unit|
[R|Contract description]
<
CallsInPlace(x, EXACTLY_ONCE)
CallsInPlace(y, EXACTLY_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|T|>(R|<local>/x|, Q|kotlin/contracts/InvocationKind|.R|kotlin/contracts/InvocationKind.EXACTLY_ONCE|)
this@R|special/anonymous|.R|kotlin/contracts/ContractBuilder.callsInPlace|<R|T|>(R|<local>/y|, Q|kotlin/contracts/InvocationKind|.R|kotlin/contracts/InvocationKind.EXACTLY_ONCE|)
}
)
}
R|<local>/x|.R|SubstitutionOverride<kotlin/Function0.invoke: R|T|>|()
R|<local>/y|.R|SubstitutionOverride<kotlin/Function0.invoke: R|T|>|()
}
@@ -3,6 +3,7 @@ import kotlin.contracts.*
fun <T> n(): T? = null
@OptIn(ExperimentalContracts::class)
fun <T> run2(x: () -> T, y: () -> T) {
contract {
callsInPlace(x, InvocationKind.EXACTLY_ONCE)
@@ -25,15 +25,20 @@ digraph postponedLambdaInReturn_kt {
subgraph cluster_3 {
color=blue
6 [label="Enter block"];
7 [label="Function call: R|/Lateinit.Lateinit|<R|R|>()" style="filled" fillcolor=yellow];
8 [label="Access variable R|<local>/builder|"];
9 [label="Function call: R|/Lateinit.Lateinit|<R|R|>().R|kotlin/apply|<R|Lateinit<R>|>(...)" style="filled" fillcolor=yellow];
10 [label="Access variable R|SubstitutionOverride</Lateinit.value: R|R|>|"];
11 [label="Jump: ^build R|/Lateinit.Lateinit|<R|R|>().R|kotlin/apply|<R|Lateinit<R>|>(R|<local>/builder|).R|SubstitutionOverride</Lateinit.value: R|R|>|"];
12 [label="Stub" style="filled" fillcolor=gray];
13 [label="Exit block" style="filled" fillcolor=gray];
subgraph cluster_4 {
color=blue
7 [label="Enter block"];
8 [label="Exit block"];
}
9 [label="Function call: R|/Lateinit.Lateinit|<R|R|>()" style="filled" fillcolor=yellow];
10 [label="Access variable R|<local>/builder|"];
11 [label="Function call: R|/Lateinit.Lateinit|<R|R|>().R|kotlin/apply|<R|Lateinit<R>|>(...)" style="filled" fillcolor=yellow];
12 [label="Access variable R|SubstitutionOverride</Lateinit.value: R|R|>|"];
13 [label="Jump: ^build R|/Lateinit.Lateinit|<R|R|>().R|kotlin/apply|<R|Lateinit<R>|>(R|<local>/builder|).R|SubstitutionOverride</Lateinit.value: R|R|>|"];
14 [label="Stub" style="filled" fillcolor=gray];
15 [label="Exit block" style="filled" fillcolor=gray];
}
14 [label="Exit function build" style="filled" fillcolor=red];
16 [label="Exit function build" style="filled" fillcolor=red];
}
5 -> {6};
6 -> {7};
@@ -41,450 +46,452 @@ digraph postponedLambdaInReturn_kt {
8 -> {9};
9 -> {10};
10 -> {11};
11 -> {14};
11 -> {12} [style=dotted];
12 -> {13} [style=dotted];
11 -> {12};
12 -> {13};
13 -> {16};
13 -> {14} [style=dotted];
subgraph cluster_4 {
color=red
15 [label="Enter property" style="filled" fillcolor=red];
16 [label="Const: Boolean(false)"];
17 [label="Exit property" style="filled" fillcolor=red];
}
15 -> {16};
16 -> {17};
14 -> {15} [style=dotted];
15 -> {16} [style=dotted];
subgraph cluster_5 {
color=red
18 [label="Enter function test1" style="filled" fillcolor=red];
subgraph cluster_6 {
25 [label="Enter property" style="filled" fillcolor=red];
26 [label="Const: Boolean(false)"];
27 [label="Exit property" style="filled" fillcolor=red];
}
25 -> {26};
26 -> {27};
subgraph cluster_6 {
color=red
28 [label="Enter function test1" style="filled" fillcolor=red];
subgraph cluster_7 {
color=blue
19 [label="Enter block"];
20 [label="Const: Null(null)"];
21 [label="Variable declaration: lvar y: R|kotlin/String?|"];
22 [label="Postponed enter to lambda"];
subgraph cluster_7 {
29 [label="Enter block"];
30 [label="Const: Null(null)"];
31 [label="Variable declaration: lvar y: R|kotlin/String?|"];
32 [label="Postponed enter to lambda"];
subgraph cluster_8 {
color=blue
30 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
subgraph cluster_8 {
40 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
subgraph cluster_9 {
color=blue
31 [label="Enter block"];
subgraph cluster_9 {
41 [label="Enter block"];
subgraph cluster_10 {
color=blue
32 [label="Enter when"];
subgraph cluster_10 {
color=blue
33 [label="Enter when branch condition "];
34 [label="Access variable R|/p|"];
35 [label="Exit when branch condition"];
}
42 [label="Enter when"];
subgraph cluster_11 {
color=blue
36 [label="Enter when branch condition else"];
37 [label="Exit when branch condition"];
43 [label="Enter when branch condition "];
44 [label="Access variable R|/p|"];
45 [label="Exit when branch condition"];
}
38 [label="Enter when branch result"];
subgraph cluster_12 {
color=blue
39 [label="Enter block"];
40 [label="Const: String()"];
41 [label="Jump: ^@run String()"];
42 [label="Stub" style="filled" fillcolor=gray];
43 [label="Exit block" style="filled" fillcolor=gray];
46 [label="Enter when branch condition else"];
47 [label="Exit when branch condition"];
}
44 [label="Exit when branch result" style="filled" fillcolor=gray];
45 [label="Enter when branch result"];
48 [label="Enter when branch result"];
subgraph cluster_13 {
color=blue
46 [label="Enter block"];
47 [label="Postponed enter to lambda"];
subgraph cluster_14 {
49 [label="Enter block"];
50 [label="Const: String()"];
51 [label="Jump: ^@run String()"];
52 [label="Stub" style="filled" fillcolor=gray];
53 [label="Exit block" style="filled" fillcolor=gray];
}
54 [label="Exit when branch result" style="filled" fillcolor=gray];
55 [label="Enter when branch result"];
subgraph cluster_14 {
color=blue
56 [label="Enter block"];
57 [label="Postponed enter to lambda"];
subgraph cluster_15 {
color=blue
57 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
subgraph cluster_15 {
67 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
subgraph cluster_16 {
color=blue
58 [label="Enter block"];
59 [label="Access variable R|<local>/y|"];
60 [label="Type operator: (R|<local>/y| as R|kotlin/String|)"];
61 [label="Const: String(...)"];
62 [label="Assignment: R|SubstitutionOverride</Lateinit.value: R|kotlin/String|>|"];
63 [label="Exit block"];
68 [label="Enter block"];
69 [label="Access variable R|<local>/y|"];
70 [label="Type operator: (R|<local>/y| as R|kotlin/String|)"];
71 [label="Const: String(...)"];
72 [label="Assignment: R|SubstitutionOverride</Lateinit.value: R|kotlin/String|>|"];
73 [label="Exit block"];
}
64 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
74 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
}
48 [label="Postponed exit from lambda"];
49 [label="Function call: R|/build|<R|kotlin/String|>(...)" style="filled" fillcolor=yellow];
50 [label="Jump: ^@run R|/build|<R|kotlin/String|>(<L> = build@fun R|Lateinit<kotlin/String>|.<anonymous>(): R|kotlin/Unit| <inline=CrossInline, kind=EXACTLY_ONCE> {
58 [label="Postponed exit from lambda"];
59 [label="Function call: R|/build|<R|kotlin/String|>(...)" style="filled" fillcolor=yellow];
60 [label="Jump: ^@run R|/build|<R|kotlin/String|>(<L> = build@fun R|Lateinit<kotlin/String>|.<anonymous>(): R|kotlin/Unit| <inline=CrossInline, kind=EXACTLY_ONCE> {
(R|<local>/y| as R|kotlin/String|)
this@R|special/anonymous|.R|SubstitutionOverride</Lateinit.value: R|kotlin/String|>| = String(...)
}
)"];
51 [label="Stub" style="filled" fillcolor=gray];
52 [label="Exit block" style="filled" fillcolor=gray];
61 [label="Stub" style="filled" fillcolor=gray];
62 [label="Exit block" style="filled" fillcolor=gray];
}
53 [label="Exit when branch result" style="filled" fillcolor=gray];
54 [label="Exit when" style="filled" fillcolor=gray];
63 [label="Exit when branch result" style="filled" fillcolor=gray];
64 [label="Exit when" style="filled" fillcolor=gray];
}
55 [label="Exit block" style="filled" fillcolor=gray];
65 [label="Exit block" style="filled" fillcolor=gray];
}
56 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
66 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
}
23 [label="Postponed exit from lambda"];
24 [label="Function call: R|kotlin/run|<R|kotlin/String|>(...)" style="filled" fillcolor=yellow];
25 [label="Variable declaration: lval x: R|kotlin/String|"];
26 [label="Access variable R|<local>/y|"];
27 [label="Access variable R|kotlin/String.length<Inapplicable(UNSAFE_CALL): kotlin/String.length>#|"];
28 [label="Exit block"];
33 [label="Postponed exit from lambda"];
34 [label="Function call: R|kotlin/run|<R|kotlin/String|>(...)" style="filled" fillcolor=yellow];
35 [label="Variable declaration: lval x: R|kotlin/String|"];
36 [label="Access variable R|<local>/y|"];
37 [label="Access variable R|kotlin/String.length<Inapplicable(UNSAFE_CALL): kotlin/String.length>#|"];
38 [label="Exit block"];
}
29 [label="Exit function test1" style="filled" fillcolor=red];
39 [label="Exit function test1" style="filled" fillcolor=red];
}
18 -> {19};
19 -> {20};
20 -> {21};
21 -> {22};
22 -> {30 24};
22 -> {23} [style=dotted];
22 -> {30} [style=dashed];
23 -> {24};
24 -> {25};
25 -> {26};
26 -> {27};
27 -> {28};
28 -> {29};
29 -> {30};
30 -> {31};
31 -> {32};
32 -> {33};
32 -> {40 34};
32 -> {33} [style=dotted];
32 -> {40} [style=dashed];
33 -> {34};
34 -> {35};
35 -> {45 36};
35 -> {36};
36 -> {37};
37 -> {38};
38 -> {39};
39 -> {40};
40 -> {41};
41 -> {56};
41 -> {42} [style=dotted];
42 -> {43} [style=dotted];
43 -> {44} [style=dotted];
44 -> {54} [style=dotted];
45 -> {46};
41 -> {42};
42 -> {43};
43 -> {44};
44 -> {45};
45 -> {55 46};
46 -> {47};
47 -> {49 57};
47 -> {48} [style=dotted];
47 -> {57} [style=dashed];
48 -> {49} [color=green];
47 -> {48};
48 -> {49};
49 -> {50};
50 -> {56};
50 -> {51} [style=dotted];
50 -> {51};
51 -> {66};
51 -> {52} [style=dotted];
52 -> {53} [style=dotted];
53 -> {54} [style=dotted];
54 -> {55} [style=dotted];
55 -> {56} [style=dotted];
56 -> {23};
57 -> {58};
58 -> {59};
54 -> {64} [style=dotted];
55 -> {56};
56 -> {57};
57 -> {59 67};
57 -> {58} [style=dotted];
57 -> {67} [style=dashed];
58 -> {59} [color=green];
59 -> {60};
60 -> {61};
61 -> {62};
62 -> {63};
63 -> {64};
64 -> {48};
subgraph cluster_16 {
color=red
65 [label="Enter function test2" style="filled" fillcolor=red];
subgraph cluster_17 {
color=blue
66 [label="Enter block"];
67 [label="Postponed enter to lambda"];
subgraph cluster_18 {
color=blue
75 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
subgraph cluster_19 {
color=blue
76 [label="Enter block"];
subgraph cluster_20 {
color=blue
77 [label="Enter while loop"];
subgraph cluster_21 {
color=blue
78 [label="Enter loop condition"];
79 [label="Const: Boolean(true)"];
80 [label="Exit loop condition"];
}
subgraph cluster_22 {
color=blue
81 [label="Enter loop block"];
subgraph cluster_23 {
color=blue
82 [label="Enter block"];
subgraph cluster_24 {
color=blue
83 [label="Try expression enter"];
subgraph cluster_25 {
color=blue
84 [label="Try main block enter"];
subgraph cluster_26 {
color=blue
85 [label="Enter block"];
86 [label="Postponed enter to lambda"];
subgraph cluster_27 {
color=blue
107 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
subgraph cluster_28 {
color=blue
108 [label="Enter block"];
109 [label="Const: String(...)"];
110 [label="Assignment: R|SubstitutionOverride</Lateinit.value: R|kotlin/String|>|"];
111 [label="Exit block"];
}
112 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
}
87 [label="Postponed exit from lambda"];
88 [label="Function call: R|/build|<R|kotlin/String|>(...)" style="filled" fillcolor=yellow];
89 [label="Jump: ^@run R|/build|<R|kotlin/String|>(<L> = build@fun R|Lateinit<kotlin/String>|.<anonymous>(): R|kotlin/Unit| <inline=CrossInline, kind=EXACTLY_ONCE> {
this@R|special/anonymous|.R|SubstitutionOverride</Lateinit.value: R|kotlin/String|>| = String(...)
}
)"];
90 [label="Stub" style="filled" fillcolor=gray];
91 [label="Exit block" style="filled" fillcolor=gray];
}
92 [label="Try main block exit" style="filled" fillcolor=gray];
}
subgraph cluster_29 {
color=blue
93 [label="Catch enter"];
94 [label="Variable declaration: e: R|kotlin/Throwable|"];
subgraph cluster_30 {
color=blue
95 [label="Enter block"];
96 [label="Exit block"];
}
97 [label="Catch exit"];
}
98 [label="Try expression exit"];
}
99 [label="Exit block"];
}
100 [label="Exit loop block"];
}
101 [label="Exit whileloop" style="filled" fillcolor=gray];
}
102 [label="Function call: R|java/lang/Exception.Exception|()" style="filled" fillcolor=gray];
103 [label="Throw: throw R|java/lang/Exception.Exception|()" style="filled" fillcolor=gray];
104 [label="Stub" style="filled" fillcolor=gray];
105 [label="Exit block" style="filled" fillcolor=gray];
}
106 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
}
68 [label="Postponed exit from lambda"];
69 [label="Function call: R|kotlin/run|<R|kotlin/String|>(...)" style="filled" fillcolor=yellow];
70 [label="Variable declaration: lval x: R|kotlin/String|"];
71 [label="Access variable R|<local>/x|"];
72 [label="Access variable R|kotlin/String.length|"];
73 [label="Exit block"];
}
74 [label="Exit function test2" style="filled" fillcolor=red];
}
65 -> {66};
66 -> {67};
67 -> {75 69};
67 -> {68} [style=dotted];
67 -> {75} [style=dashed];
60 -> {66};
60 -> {61} [style=dotted];
61 -> {62} [style=dotted];
62 -> {63} [style=dotted];
63 -> {64} [style=dotted];
64 -> {65} [style=dotted];
65 -> {66} [style=dotted];
66 -> {33};
67 -> {68};
68 -> {69};
69 -> {70};
70 -> {71};
71 -> {72};
72 -> {73};
73 -> {74};
74 -> {58};
subgraph cluster_17 {
color=red
75 [label="Enter function test2" style="filled" fillcolor=red];
subgraph cluster_18 {
color=blue
76 [label="Enter block"];
77 [label="Postponed enter to lambda"];
subgraph cluster_19 {
color=blue
85 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
subgraph cluster_20 {
color=blue
86 [label="Enter block"];
subgraph cluster_21 {
color=blue
87 [label="Enter while loop"];
subgraph cluster_22 {
color=blue
88 [label="Enter loop condition"];
89 [label="Const: Boolean(true)"];
90 [label="Exit loop condition"];
}
subgraph cluster_23 {
color=blue
91 [label="Enter loop block"];
subgraph cluster_24 {
color=blue
92 [label="Enter block"];
subgraph cluster_25 {
color=blue
93 [label="Try expression enter"];
subgraph cluster_26 {
color=blue
94 [label="Try main block enter"];
subgraph cluster_27 {
color=blue
95 [label="Enter block"];
96 [label="Postponed enter to lambda"];
subgraph cluster_28 {
color=blue
117 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
subgraph cluster_29 {
color=blue
118 [label="Enter block"];
119 [label="Const: String(...)"];
120 [label="Assignment: R|SubstitutionOverride</Lateinit.value: R|kotlin/String|>|"];
121 [label="Exit block"];
}
122 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
}
97 [label="Postponed exit from lambda"];
98 [label="Function call: R|/build|<R|kotlin/String|>(...)" style="filled" fillcolor=yellow];
99 [label="Jump: ^@run R|/build|<R|kotlin/String|>(<L> = build@fun R|Lateinit<kotlin/String>|.<anonymous>(): R|kotlin/Unit| <inline=CrossInline, kind=EXACTLY_ONCE> {
this@R|special/anonymous|.R|SubstitutionOverride</Lateinit.value: R|kotlin/String|>| = String(...)
}
)"];
100 [label="Stub" style="filled" fillcolor=gray];
101 [label="Exit block" style="filled" fillcolor=gray];
}
102 [label="Try main block exit" style="filled" fillcolor=gray];
}
subgraph cluster_30 {
color=blue
103 [label="Catch enter"];
104 [label="Variable declaration: e: R|kotlin/Throwable|"];
subgraph cluster_31 {
color=blue
105 [label="Enter block"];
106 [label="Exit block"];
}
107 [label="Catch exit"];
}
108 [label="Try expression exit"];
}
109 [label="Exit block"];
}
110 [label="Exit loop block"];
}
111 [label="Exit whileloop" style="filled" fillcolor=gray];
}
112 [label="Function call: R|java/lang/Exception.Exception|()" style="filled" fillcolor=gray];
113 [label="Throw: throw R|java/lang/Exception.Exception|()" style="filled" fillcolor=gray];
114 [label="Stub" style="filled" fillcolor=gray];
115 [label="Exit block" style="filled" fillcolor=gray];
}
116 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
}
78 [label="Postponed exit from lambda"];
79 [label="Function call: R|kotlin/run|<R|kotlin/String|>(...)" style="filled" fillcolor=yellow];
80 [label="Variable declaration: lval x: R|kotlin/String|"];
81 [label="Access variable R|<local>/x|"];
82 [label="Access variable R|kotlin/String.length|"];
83 [label="Exit block"];
}
84 [label="Exit function test2" style="filled" fillcolor=red];
}
75 -> {76};
76 -> {77};
77 -> {78};
77 -> {85 79};
77 -> {78} [style=dotted];
77 -> {85} [style=dashed];
78 -> {79};
79 -> {80};
80 -> {81};
80 -> {101} [style=dotted];
81 -> {82};
82 -> {83};
83 -> {84 93};
84 -> {85};
83 -> {84};
85 -> {86};
86 -> {88 107};
86 -> {87} [style=dotted];
86 -> {107} [style=dashed];
87 -> {88} [color=green];
86 -> {87};
87 -> {88};
88 -> {89};
89 -> {106};
89 -> {90} [style=dotted];
90 -> {91} [style=dotted];
91 -> {92} [style=dotted];
92 -> {98 93} [style=dotted];
93 -> {94};
93 -> {74} [label=onUncaughtException];
89 -> {90};
90 -> {91};
90 -> {111} [style=dotted];
91 -> {92};
92 -> {93};
93 -> {94 103};
94 -> {95};
95 -> {96};
96 -> {97};
97 -> {98};
96 -> {98 117};
96 -> {97} [style=dotted];
96 -> {117} [style=dashed];
97 -> {98} [color=green];
98 -> {99};
99 -> {100};
100 -> {78} [color=green style=dashed];
99 -> {116};
99 -> {100} [style=dotted];
100 -> {101} [style=dotted];
101 -> {102} [style=dotted];
102 -> {103} [style=dotted];
103 -> {104} [style=dotted];
103 -> {74} [style=dotted] [label=onUncaughtException];
104 -> {105} [style=dotted];
105 -> {106} [style=dotted];
106 -> {68};
102 -> {108 103} [style=dotted];
103 -> {104};
103 -> {84} [label=onUncaughtException];
104 -> {105};
105 -> {106};
106 -> {107};
107 -> {108};
108 -> {109};
109 -> {110};
110 -> {111};
111 -> {112};
112 -> {87};
110 -> {88} [color=green style=dashed];
111 -> {112} [style=dotted];
112 -> {113} [style=dotted];
113 -> {114} [style=dotted];
113 -> {84} [style=dotted] [label=onUncaughtException];
114 -> {115} [style=dotted];
115 -> {116} [style=dotted];
116 -> {78};
117 -> {118};
118 -> {119};
119 -> {120};
120 -> {121};
121 -> {122};
122 -> {97};
subgraph cluster_31 {
subgraph cluster_32 {
color=red
113 [label="Enter function test3" style="filled" fillcolor=red];
subgraph cluster_32 {
123 [label="Enter function test3" style="filled" fillcolor=red];
subgraph cluster_33 {
color=blue
114 [label="Enter block"];
115 [label="Variable declaration: lvar y: R|kotlin/String?|"];
116 [label="Const: String()"];
117 [label="Assignment: R|<local>/y|"];
118 [label="Postponed enter to lambda"];
subgraph cluster_33 {
124 [label="Enter block"];
125 [label="Variable declaration: lvar y: R|kotlin/String?|"];
126 [label="Const: String()"];
127 [label="Assignment: R|<local>/y|"];
128 [label="Postponed enter to lambda"];
subgraph cluster_34 {
color=blue
127 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
subgraph cluster_34 {
137 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
subgraph cluster_35 {
color=blue
128 [label="Enter block"];
subgraph cluster_35 {
138 [label="Enter block"];
subgraph cluster_36 {
color=blue
129 [label="Enter when"];
subgraph cluster_36 {
color=blue
130 [label="Enter when branch condition "];
131 [label="Access variable R|/p|"];
132 [label="Function call: R|/p|.R|kotlin/Boolean.not|()" style="filled" fillcolor=yellow];
133 [label="Exit when branch condition"];
}
139 [label="Enter when"];
subgraph cluster_37 {
color=blue
134 [label="Enter when branch condition else"];
135 [label="Exit when branch condition"];
140 [label="Enter when branch condition "];
141 [label="Access variable R|/p|"];
142 [label="Function call: R|/p|.R|kotlin/Boolean.not|()" style="filled" fillcolor=yellow];
143 [label="Exit when branch condition"];
}
136 [label="Enter when branch result"];
subgraph cluster_38 {
color=blue
137 [label="Enter block"];
138 [label="Const: String()"];
139 [label="Jump: ^@run String()"];
140 [label="Stub" style="filled" fillcolor=gray];
141 [label="Exit block" style="filled" fillcolor=gray];
144 [label="Enter when branch condition else"];
145 [label="Exit when branch condition"];
}
142 [label="Exit when branch result" style="filled" fillcolor=gray];
143 [label="Enter when branch result"];
146 [label="Enter when branch result"];
subgraph cluster_39 {
color=blue
144 [label="Enter block"];
145 [label="Postponed enter to lambda"];
subgraph cluster_40 {
147 [label="Enter block"];
148 [label="Const: String()"];
149 [label="Jump: ^@run String()"];
150 [label="Stub" style="filled" fillcolor=gray];
151 [label="Exit block" style="filled" fillcolor=gray];
}
152 [label="Exit when branch result" style="filled" fillcolor=gray];
153 [label="Enter when branch result"];
subgraph cluster_40 {
color=blue
154 [label="Enter block"];
155 [label="Postponed enter to lambda"];
subgraph cluster_41 {
color=blue
155 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
subgraph cluster_41 {
165 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
subgraph cluster_42 {
color=blue
156 [label="Enter block"];
157 [label="Const: Null(null)"];
158 [label="Assignment: R|<local>/y|"];
159 [label="Const: String(...)"];
160 [label="Assignment: R|SubstitutionOverride</Lateinit.value: R|kotlin/String|>|"];
161 [label="Exit block"];
166 [label="Enter block"];
167 [label="Const: Null(null)"];
168 [label="Assignment: R|<local>/y|"];
169 [label="Const: String(...)"];
170 [label="Assignment: R|SubstitutionOverride</Lateinit.value: R|kotlin/String|>|"];
171 [label="Exit block"];
}
162 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
172 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
}
146 [label="Postponed exit from lambda"];
147 [label="Function call: R|/build|<R|kotlin/String|>(...)" style="filled" fillcolor=yellow];
148 [label="Jump: ^@run R|/build|<R|kotlin/String|>(<L> = build@fun R|Lateinit<kotlin/String>|.<anonymous>(): R|kotlin/Unit| <inline=CrossInline, kind=EXACTLY_ONCE> {
156 [label="Postponed exit from lambda"];
157 [label="Function call: R|/build|<R|kotlin/String|>(...)" style="filled" fillcolor=yellow];
158 [label="Jump: ^@run R|/build|<R|kotlin/String|>(<L> = build@fun R|Lateinit<kotlin/String>|.<anonymous>(): R|kotlin/Unit| <inline=CrossInline, kind=EXACTLY_ONCE> {
R|<local>/y| = Null(null)
this@R|special/anonymous|.R|SubstitutionOverride</Lateinit.value: R|kotlin/String|>| = String(...)
}
)"];
149 [label="Stub" style="filled" fillcolor=gray];
150 [label="Exit block" style="filled" fillcolor=gray];
159 [label="Stub" style="filled" fillcolor=gray];
160 [label="Exit block" style="filled" fillcolor=gray];
}
151 [label="Exit when branch result" style="filled" fillcolor=gray];
152 [label="Exit when" style="filled" fillcolor=gray];
161 [label="Exit when branch result" style="filled" fillcolor=gray];
162 [label="Exit when" style="filled" fillcolor=gray];
}
153 [label="Exit block" style="filled" fillcolor=gray];
163 [label="Exit block" style="filled" fillcolor=gray];
}
154 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
164 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
}
119 [label="Postponed exit from lambda"];
120 [label="Function call: R|kotlin/run|<R|kotlin/String|>(...)" style="filled" fillcolor=yellow];
121 [label="Variable declaration: lval x: R|kotlin/String|"];
122 [label="Access variable R|<local>/y|"];
123 [label="Smart cast: R|<local>/y|"];
124 [label="Access variable R|kotlin/String.length|"];
125 [label="Exit block"];
129 [label="Postponed exit from lambda"];
130 [label="Function call: R|kotlin/run|<R|kotlin/String|>(...)" style="filled" fillcolor=yellow];
131 [label="Variable declaration: lval x: R|kotlin/String|"];
132 [label="Access variable R|<local>/y|"];
133 [label="Smart cast: R|<local>/y|"];
134 [label="Access variable R|kotlin/String.length|"];
135 [label="Exit block"];
}
126 [label="Exit function test3" style="filled" fillcolor=red];
136 [label="Exit function test3" style="filled" fillcolor=red];
}
113 -> {114};
114 -> {115};
115 -> {116};
116 -> {117};
117 -> {118};
118 -> {127 120};
118 -> {119} [style=dotted];
118 -> {127} [style=dashed];
119 -> {120};
120 -> {121};
121 -> {122};
122 -> {123};
123 -> {124};
124 -> {125};
125 -> {126};
126 -> {127};
127 -> {128};
128 -> {129};
128 -> {137 130};
128 -> {129} [style=dotted];
128 -> {137} [style=dashed];
129 -> {130};
130 -> {131};
131 -> {132};
132 -> {133};
133 -> {143 134};
133 -> {134};
134 -> {135};
135 -> {136};
136 -> {137};
137 -> {138};
138 -> {139};
139 -> {154};
139 -> {140} [style=dotted];
140 -> {141} [style=dotted];
141 -> {142} [style=dotted];
142 -> {152} [style=dotted];
143 -> {144};
139 -> {140};
140 -> {141};
141 -> {142};
142 -> {143};
143 -> {153 144};
144 -> {145};
145 -> {147 155};
145 -> {146} [style=dotted];
145 -> {155} [style=dashed];
146 -> {147} [color=green];
145 -> {146};
146 -> {147};
147 -> {148};
148 -> {154};
148 -> {149} [style=dotted];
148 -> {149};
149 -> {164};
149 -> {150} [style=dotted];
150 -> {151} [style=dotted];
151 -> {152} [style=dotted];
152 -> {153} [style=dotted];
153 -> {154} [style=dotted];
154 -> {119};
155 -> {156};
156 -> {157};
152 -> {162} [style=dotted];
153 -> {154};
154 -> {155};
155 -> {157 165};
155 -> {156} [style=dotted];
155 -> {165} [style=dashed];
156 -> {157} [color=green];
157 -> {158};
158 -> {159};
159 -> {160};
160 -> {161};
161 -> {162};
162 -> {146};
158 -> {164};
158 -> {159} [style=dotted];
159 -> {160} [style=dotted];
160 -> {161} [style=dotted];
161 -> {162} [style=dotted];
162 -> {163} [style=dotted];
163 -> {164} [style=dotted];
164 -> {129};
165 -> {166};
166 -> {167};
167 -> {168};
168 -> {169};
169 -> {170};
170 -> {171};
171 -> {172};
172 -> {156};
}
@@ -15,7 +15,13 @@ FILE: postponedLambdaInReturn.kt
CallsInPlace(builder, EXACTLY_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>/builder|, Q|kotlin/contracts/InvocationKind|.R|kotlin/contracts/InvocationKind.EXACTLY_ONCE|)
}
)
}
^build R|/Lateinit.Lateinit|<R|R|>().R|kotlin/apply|<R|Lateinit<R>|>(R|<local>/builder|).R|SubstitutionOverride</Lateinit.value: R|R|>|
}
public final val p: R|kotlin/Boolean| = Boolean(false)
@@ -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
}
@@ -9,124 +9,138 @@ digraph atLeastOnce_kt {
subgraph cluster_1 {
color=blue
1 [label="Enter block"];
2 [label="Function call: R|<local>/block|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()" style="filled" fillcolor=yellow];
3 [label="Exit block"];
subgraph cluster_2 {
color=blue
2 [label="Enter block"];
3 [label="Exit block"];
}
4 [label="Function call: R|<local>/block|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()" style="filled" fillcolor=yellow];
5 [label="Exit block"];
}
4 [label="Exit function inlineRun" style="filled" fillcolor=red];
6 [label="Exit function inlineRun" style="filled" fillcolor=red];
}
0 -> {1};
1 -> {2};
2 -> {3};
3 -> {4};
subgraph cluster_2 {
color=red
5 [label="Enter function myRun" style="filled" fillcolor=red];
subgraph cluster_3 {
color=blue
6 [label="Enter block"];
7 [label="Function call: R|<local>/block|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()" style="filled" fillcolor=yellow];
8 [label="Exit block"];
}
9 [label="Exit function myRun" style="filled" fillcolor=red];
}
4 -> {5};
5 -> {6};
6 -> {7};
7 -> {8};
8 -> {9};
subgraph cluster_4 {
subgraph cluster_3 {
color=red
10 [label="Enter function test_1" style="filled" fillcolor=red];
subgraph cluster_5 {
15 [label="Enter function myRun" style="filled" fillcolor=red];
subgraph cluster_4 {
color=blue
11 [label="Enter block"];
12 [label="Variable declaration: lval x: R|kotlin/Int|"];
13 [label="Postponed enter to lambda"];
subgraph cluster_6 {
16 [label="Enter block"];
subgraph cluster_5 {
color=blue
20 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
subgraph cluster_7 {
color=blue
21 [label="Enter block"];
22 [label="Const: Int(1)"];
23 [label="Assignment: R|<local>/x|"];
24 [label="Exit block"];
}
25 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
17 [label="Enter block"];
18 [label="Exit block"];
}
14 [label="Postponed exit from lambda"];
15 [label="Function call: R|/inlineRun|(...)" style="filled" fillcolor=yellow];
16 [label="Access variable R|<local>/x|"];
17 [label="Function call: R|<local>/x|.R|kotlin/Int.inc|()" style="filled" fillcolor=yellow];
18 [label="Exit block"];
19 [label="Function call: R|<local>/block|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()" style="filled" fillcolor=yellow];
20 [label="Exit block"];
}
19 [label="Exit function test_1" style="filled" fillcolor=red];
21 [label="Exit function myRun" style="filled" fillcolor=red];
}
10 -> {11};
11 -> {12};
12 -> {13};
13 -> {20 15};
13 -> {14} [style=dotted];
13 -> {20} [style=dashed];
14 -> {15};
14 -> {13} [color=green style=dashed];
15 -> {16};
16 -> {17};
17 -> {18};
18 -> {19};
19 -> {20};
20 -> {21};
21 -> {22};
22 -> {23};
23 -> {24};
24 -> {25};
25 -> {14};
subgraph cluster_8 {
subgraph cluster_6 {
color=red
26 [label="Enter function test_2" style="filled" fillcolor=red];
subgraph cluster_9 {
30 [label="Enter function test_1" style="filled" fillcolor=red];
subgraph cluster_7 {
color=blue
27 [label="Enter block"];
28 [label="Variable declaration: lval x: R|kotlin/Int|"];
29 [label="Postponed enter to lambda"];
subgraph cluster_10 {
31 [label="Enter block"];
32 [label="Variable declaration: lval x: R|kotlin/Int|"];
33 [label="Postponed enter to lambda"];
subgraph cluster_8 {
color=blue
36 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
subgraph cluster_11 {
40 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
subgraph cluster_9 {
color=blue
37 [label="Enter block"];
38 [label="Const: Int(1)"];
39 [label="Assignment: R|<local>/x|"];
40 [label="Exit block"];
41 [label="Enter block"];
42 [label="Const: Int(1)"];
43 [label="Assignment: R|<local>/x|"];
44 [label="Exit block"];
}
41 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
45 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
}
30 [label="Postponed exit from lambda"];
31 [label="Function call: R|/myRun|(...)" style="filled" fillcolor=yellow];
32 [label="Access variable R|<local>/x|"];
33 [label="Function call: R|<local>/x|.R|kotlin/Int.inc|()" style="filled" fillcolor=yellow];
34 [label="Exit block"];
34 [label="Postponed exit from lambda"];
35 [label="Function call: R|/inlineRun|(...)" style="filled" fillcolor=yellow];
36 [label="Access variable R|<local>/x|"];
37 [label="Function call: R|<local>/x|.R|kotlin/Int.inc|()" style="filled" fillcolor=yellow];
38 [label="Exit block"];
}
35 [label="Exit function test_2" style="filled" fillcolor=red];
39 [label="Exit function test_1" style="filled" fillcolor=red];
}
26 -> {27};
27 -> {28};
28 -> {29};
29 -> {36 31};
29 -> {30} [style=dotted];
29 -> {36} [style=dashed];
30 -> {31};
30 -> {29} [color=green style=dashed];
31 -> {32};
32 -> {33};
33 -> {34};
33 -> {40 35};
33 -> {34} [style=dotted];
33 -> {40} [style=dashed];
34 -> {35};
34 -> {33} [color=green style=dashed];
35 -> {36};
36 -> {37};
37 -> {38};
38 -> {39};
39 -> {40};
40 -> {41};
41 -> {30};
41 -> {42};
42 -> {43};
43 -> {44};
44 -> {45};
45 -> {34};
subgraph cluster_10 {
color=red
46 [label="Enter function test_2" style="filled" fillcolor=red];
subgraph cluster_11 {
color=blue
47 [label="Enter block"];
48 [label="Variable declaration: lval x: R|kotlin/Int|"];
49 [label="Postponed enter to lambda"];
subgraph cluster_12 {
color=blue
56 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
subgraph cluster_13 {
color=blue
57 [label="Enter block"];
58 [label="Const: Int(1)"];
59 [label="Assignment: R|<local>/x|"];
60 [label="Exit block"];
}
61 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
}
50 [label="Postponed exit from lambda"];
51 [label="Function call: R|/myRun|(...)" style="filled" fillcolor=yellow];
52 [label="Access variable R|<local>/x|"];
53 [label="Function call: R|<local>/x|.R|kotlin/Int.inc|()" style="filled" fillcolor=yellow];
54 [label="Exit block"];
}
55 [label="Exit function test_2" style="filled" fillcolor=red];
}
46 -> {47};
47 -> {48};
48 -> {49};
49 -> {56 51};
49 -> {50} [style=dotted];
49 -> {56} [style=dashed];
50 -> {51};
50 -> {49} [color=green style=dashed];
51 -> {52};
52 -> {53};
53 -> {54};
54 -> {55};
56 -> {57};
57 -> {58};
58 -> {59};
59 -> {60};
60 -> {61};
61 -> {50};
}
@@ -1,20 +1,32 @@
FILE: atLeastOnce.kt
public final inline fun inlineRun(block: R|() -> kotlin/Unit|): R|kotlin/Unit|
@R|kotlin/OptIn|(markerClass = vararg(<getClass>(Q|kotlin/contracts/ExperimentalContracts|))) public final inline fun inlineRun(block: R|() -> kotlin/Unit|): R|kotlin/Unit|
[R|Contract description]
<
CallsInPlace(block, AT_LEAST_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>/block|, Q|kotlin/contracts/InvocationKind|.R|kotlin/contracts/InvocationKind.AT_LEAST_ONCE|)
}
)
}
R|<local>/block|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()
}
public final fun myRun(block: R|() -> kotlin/Unit|): R|kotlin/Unit|
@R|kotlin/OptIn|(markerClass = vararg(<getClass>(Q|kotlin/contracts/ExperimentalContracts|))) public final fun myRun(block: R|() -> kotlin/Unit|): R|kotlin/Unit|
[R|Contract description]
<
CallsInPlace(block, AT_LEAST_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>/block|, Q|kotlin/contracts/InvocationKind|.R|kotlin/contracts/InvocationKind.AT_LEAST_ONCE|)
}
)
}
R|<local>/block|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()
}
public final fun test_1(): R|kotlin/Unit| {
@@ -2,6 +2,7 @@
import kotlin.contracts.*
@OptIn(ExperimentalContracts::class)
inline fun inlineRun(block: () -> Unit) {
contract {
callsInPlace(block, InvocationKind.AT_LEAST_ONCE)
@@ -9,6 +10,7 @@ inline fun inlineRun(block: () -> Unit) {
block()
}
@OptIn(ExperimentalContracts::class)
fun myRun(block: () -> Unit) {
contract {
callsInPlace(block, InvocationKind.AT_LEAST_ONCE)
@@ -9,120 +9,134 @@ digraph atMostOnce_kt {
subgraph cluster_1 {
color=blue
1 [label="Enter block"];
2 [label="Function call: R|<local>/block|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()" style="filled" fillcolor=yellow];
3 [label="Exit block"];
subgraph cluster_2 {
color=blue
2 [label="Enter block"];
3 [label="Exit block"];
}
4 [label="Function call: R|<local>/block|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()" style="filled" fillcolor=yellow];
5 [label="Exit block"];
}
4 [label="Exit function inlineRun" style="filled" fillcolor=red];
6 [label="Exit function inlineRun" style="filled" fillcolor=red];
}
0 -> {1};
1 -> {2};
2 -> {3};
3 -> {4};
subgraph cluster_2 {
color=red
5 [label="Enter function myRun" style="filled" fillcolor=red];
subgraph cluster_3 {
color=blue
6 [label="Enter block"];
7 [label="Function call: R|<local>/block|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()" style="filled" fillcolor=yellow];
8 [label="Exit block"];
}
9 [label="Exit function myRun" style="filled" fillcolor=red];
}
4 -> {5};
5 -> {6};
6 -> {7};
7 -> {8};
8 -> {9};
subgraph cluster_4 {
subgraph cluster_3 {
color=red
10 [label="Enter function test_1" style="filled" fillcolor=red];
subgraph cluster_5 {
15 [label="Enter function myRun" style="filled" fillcolor=red];
subgraph cluster_4 {
color=blue
11 [label="Enter block"];
12 [label="Variable declaration: lval x: R|kotlin/Int|"];
13 [label="Postponed enter to lambda"];
subgraph cluster_6 {
16 [label="Enter block"];
subgraph cluster_5 {
color=blue
20 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
subgraph cluster_7 {
color=blue
21 [label="Enter block"];
22 [label="Const: Int(1)"];
23 [label="Assignment: R|<local>/x|"];
24 [label="Exit block"];
}
25 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
17 [label="Enter block"];
18 [label="Exit block"];
}
14 [label="Postponed exit from lambda"];
15 [label="Function call: R|/inlineRun|(...)" style="filled" fillcolor=yellow];
16 [label="Access variable R|<local>/x|"];
17 [label="Function call: R|<local>/x|.R|kotlin/Int.inc|()" style="filled" fillcolor=yellow];
18 [label="Exit block"];
19 [label="Function call: R|<local>/block|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()" style="filled" fillcolor=yellow];
20 [label="Exit block"];
}
19 [label="Exit function test_1" style="filled" fillcolor=red];
21 [label="Exit function myRun" style="filled" fillcolor=red];
}
10 -> {11};
11 -> {12};
12 -> {13};
13 -> {14 20 15};
13 -> {20} [style=dashed];
14 -> {15};
15 -> {16};
16 -> {17};
17 -> {18};
18 -> {19};
19 -> {20};
20 -> {21};
21 -> {22};
22 -> {23};
23 -> {24};
24 -> {25};
25 -> {14};
subgraph cluster_8 {
subgraph cluster_6 {
color=red
26 [label="Enter function test_2" style="filled" fillcolor=red];
subgraph cluster_9 {
30 [label="Enter function test_1" style="filled" fillcolor=red];
subgraph cluster_7 {
color=blue
27 [label="Enter block"];
28 [label="Variable declaration: lval x: R|kotlin/Int|"];
29 [label="Postponed enter to lambda"];
subgraph cluster_10 {
31 [label="Enter block"];
32 [label="Variable declaration: lval x: R|kotlin/Int|"];
33 [label="Postponed enter to lambda"];
subgraph cluster_8 {
color=blue
36 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
subgraph cluster_11 {
40 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
subgraph cluster_9 {
color=blue
37 [label="Enter block"];
38 [label="Const: Int(1)"];
39 [label="Assignment: R|<local>/x|"];
40 [label="Exit block"];
41 [label="Enter block"];
42 [label="Const: Int(1)"];
43 [label="Assignment: R|<local>/x|"];
44 [label="Exit block"];
}
41 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
45 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
}
30 [label="Postponed exit from lambda"];
31 [label="Function call: R|/myRun|(...)" style="filled" fillcolor=yellow];
32 [label="Access variable R|<local>/x|"];
33 [label="Function call: R|<local>/x|.R|kotlin/Int.inc|()" style="filled" fillcolor=yellow];
34 [label="Exit block"];
34 [label="Postponed exit from lambda"];
35 [label="Function call: R|/inlineRun|(...)" style="filled" fillcolor=yellow];
36 [label="Access variable R|<local>/x|"];
37 [label="Function call: R|<local>/x|.R|kotlin/Int.inc|()" style="filled" fillcolor=yellow];
38 [label="Exit block"];
}
35 [label="Exit function test_2" style="filled" fillcolor=red];
39 [label="Exit function test_1" style="filled" fillcolor=red];
}
26 -> {27};
27 -> {28};
28 -> {29};
29 -> {30 36 31};
29 -> {36} [style=dashed];
30 -> {31};
31 -> {32};
32 -> {33};
33 -> {34};
33 -> {34 40 35};
33 -> {40} [style=dashed];
34 -> {35};
35 -> {36};
36 -> {37};
37 -> {38};
38 -> {39};
39 -> {40};
40 -> {41};
41 -> {30};
41 -> {42};
42 -> {43};
43 -> {44};
44 -> {45};
45 -> {34};
subgraph cluster_10 {
color=red
46 [label="Enter function test_2" style="filled" fillcolor=red];
subgraph cluster_11 {
color=blue
47 [label="Enter block"];
48 [label="Variable declaration: lval x: R|kotlin/Int|"];
49 [label="Postponed enter to lambda"];
subgraph cluster_12 {
color=blue
56 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
subgraph cluster_13 {
color=blue
57 [label="Enter block"];
58 [label="Const: Int(1)"];
59 [label="Assignment: R|<local>/x|"];
60 [label="Exit block"];
}
61 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
}
50 [label="Postponed exit from lambda"];
51 [label="Function call: R|/myRun|(...)" style="filled" fillcolor=yellow];
52 [label="Access variable R|<local>/x|"];
53 [label="Function call: R|<local>/x|.R|kotlin/Int.inc|()" style="filled" fillcolor=yellow];
54 [label="Exit block"];
}
55 [label="Exit function test_2" style="filled" fillcolor=red];
}
46 -> {47};
47 -> {48};
48 -> {49};
49 -> {50 56 51};
49 -> {56} [style=dashed];
50 -> {51};
51 -> {52};
52 -> {53};
53 -> {54};
54 -> {55};
56 -> {57};
57 -> {58};
58 -> {59};
59 -> {60};
60 -> {61};
61 -> {50};
}
@@ -1,20 +1,32 @@
FILE: atMostOnce.kt
public final inline fun inlineRun(block: R|() -> kotlin/Unit|): R|kotlin/Unit|
@R|kotlin/OptIn|(markerClass = vararg(<getClass>(Q|kotlin/contracts/ExperimentalContracts|))) public final inline fun inlineRun(block: R|() -> kotlin/Unit|): R|kotlin/Unit|
[R|Contract description]
<
CallsInPlace(block, 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>/block|, Q|kotlin/contracts/InvocationKind|.R|kotlin/contracts/InvocationKind.AT_MOST_ONCE|)
}
)
}
R|<local>/block|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()
}
public final fun myRun(block: R|() -> kotlin/Unit|): R|kotlin/Unit|
@R|kotlin/OptIn|(markerClass = vararg(<getClass>(Q|kotlin/contracts/ExperimentalContracts|))) public final fun myRun(block: R|() -> kotlin/Unit|): R|kotlin/Unit|
[R|Contract description]
<
CallsInPlace(block, 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>/block|, Q|kotlin/contracts/InvocationKind|.R|kotlin/contracts/InvocationKind.AT_MOST_ONCE|)
}
)
}
R|<local>/block|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()
}
public final fun test_1(): R|kotlin/Unit| {
@@ -2,6 +2,7 @@
import kotlin.contracts.*
@OptIn(ExperimentalContracts::class)
inline fun inlineRun(block: () -> Unit) {
contract {
callsInPlace(block, InvocationKind.AT_MOST_ONCE)
@@ -9,6 +10,7 @@ inline fun inlineRun(block: () -> Unit) {
block()
}
@OptIn(ExperimentalContracts::class)
fun myRun(block: () -> Unit) {
contract {
callsInPlace(block, InvocationKind.AT_MOST_ONCE)
@@ -9,123 +9,144 @@ digraph contractsUsage_kt {
subgraph cluster_1 {
color=blue
1 [label="Enter block"];
2 [label="Access variable R|<local>/x|"];
3 [label="Function call: R|<local>/x|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()" style="filled" fillcolor=yellow];
4 [label="Exit block"];
subgraph cluster_2 {
color=blue
2 [label="Enter block"];
3 [label="Exit block"];
}
4 [label="Access variable R|<local>/x|"];
5 [label="Function call: R|<local>/x|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()" style="filled" fillcolor=yellow];
6 [label="Exit block"];
}
5 [label="Exit function bar" style="filled" fillcolor=red];
7 [label="Exit function bar" style="filled" fillcolor=red];
}
0 -> {1};
1 -> {2};
2 -> {3};
3 -> {4};
4 -> {5};
subgraph cluster_2 {
color=red
6 [label="Enter function baz" style="filled" fillcolor=red];
subgraph cluster_3 {
color=blue
7 [label="Enter block"];
subgraph cluster_4 {
color=blue
8 [label="Enter when"];
subgraph cluster_5 {
color=blue
9 [label="Enter when branch condition "];
10 [label="Const: Boolean(true)"];
11 [label="Exit when branch condition"];
}
12 [label="Synthetic else branch"];
13 [label="Enter when branch result"];
subgraph cluster_6 {
color=blue
14 [label="Enter block"];
15 [label="Access variable this@R|/baz|"];
16 [label="Function call: this@R|/baz|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()" style="filled" fillcolor=yellow];
17 [label="Exit block"];
}
18 [label="Exit when branch result"];
19 [label="Exit when"];
}
20 [label="Exit block"];
}
21 [label="Exit function baz" style="filled" fillcolor=red];
}
5 -> {6};
6 -> {7};
7 -> {8};
8 -> {9};
9 -> {10};
10 -> {11};
11 -> {13 12};
12 -> {19};
13 -> {14};
14 -> {15};
15 -> {16};
subgraph cluster_3 {
color=red
16 [label="Enter function baz" style="filled" fillcolor=red];
subgraph cluster_4 {
color=blue
17 [label="Enter block"];
subgraph cluster_5 {
color=blue
18 [label="Enter block"];
19 [label="Exit block"];
}
subgraph cluster_6 {
color=blue
20 [label="Enter when"];
subgraph cluster_7 {
color=blue
21 [label="Enter when branch condition "];
22 [label="Const: Boolean(true)"];
23 [label="Exit when branch condition"];
}
24 [label="Synthetic else branch"];
25 [label="Enter when branch result"];
subgraph cluster_8 {
color=blue
26 [label="Enter block"];
27 [label="Access variable this@R|/baz|"];
28 [label="Function call: this@R|/baz|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()" style="filled" fillcolor=yellow];
29 [label="Exit block"];
}
30 [label="Exit when branch result"];
31 [label="Exit when"];
}
32 [label="Exit block"];
}
33 [label="Exit function baz" style="filled" fillcolor=red];
}
16 -> {17};
17 -> {18};
18 -> {19};
19 -> {20};
20 -> {21};
subgraph cluster_7 {
color=red
22 [label="Enter function foo" style="filled" fillcolor=red];
subgraph cluster_8 {
color=blue
23 [label="Enter block"];
subgraph cluster_9 {
color=blue
24 [label="Enter when"];
subgraph cluster_10 {
color=blue
25 [label="Enter when branch condition "];
26 [label="Const: Boolean(true)"];
27 [label="Exit when branch condition"];
}
28 [label="Synthetic else branch"];
29 [label="Enter when branch result"];
subgraph cluster_11 {
color=blue
30 [label="Enter block"];
31 [label="Access variable R|<local>/x|"];
32 [label="Function call: R|<local>/x|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()" style="filled" fillcolor=yellow];
33 [label="Access variable R|<local>/y|"];
34 [label="Function call: R|<local>/y|.R|/baz|()" style="filled" fillcolor=yellow];
35 [label="Jump: ^foo Unit"];
36 [label="Stub" style="filled" fillcolor=gray];
37 [label="Exit block" style="filled" fillcolor=gray];
}
38 [label="Exit when branch result" style="filled" fillcolor=gray];
39 [label="Exit when"];
}
40 [label="Access variable R|<local>/x|"];
41 [label="Function call: R|/bar|(...)" style="filled" fillcolor=yellow];
42 [label="Exit block"];
}
43 [label="Exit function foo" style="filled" fillcolor=red];
}
21 -> {22};
22 -> {23};
23 -> {24};
24 -> {25};
23 -> {25 24};
24 -> {31};
25 -> {26};
26 -> {27};
27 -> {29 28};
28 -> {39};
27 -> {28};
28 -> {29};
29 -> {30};
30 -> {31};
31 -> {32};
32 -> {33};
33 -> {34};
34 -> {35};
35 -> {43};
35 -> {36} [style=dotted];
36 -> {37} [style=dotted];
37 -> {38} [style=dotted];
38 -> {39} [style=dotted];
39 -> {40};
40 -> {41};
41 -> {42};
subgraph cluster_9 {
color=red
42 [label="Enter function foo" style="filled" fillcolor=red];
subgraph cluster_10 {
color=blue
43 [label="Enter block"];
subgraph cluster_11 {
color=blue
44 [label="Enter block"];
45 [label="Exit block"];
}
subgraph cluster_12 {
color=blue
46 [label="Enter when"];
subgraph cluster_13 {
color=blue
47 [label="Enter when branch condition "];
48 [label="Const: Boolean(true)"];
49 [label="Exit when branch condition"];
}
50 [label="Synthetic else branch"];
51 [label="Enter when branch result"];
subgraph cluster_14 {
color=blue
52 [label="Enter block"];
53 [label="Access variable R|<local>/x|"];
54 [label="Function call: R|<local>/x|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()" style="filled" fillcolor=yellow];
55 [label="Access variable R|<local>/y|"];
56 [label="Function call: R|<local>/y|.R|/baz|()" style="filled" fillcolor=yellow];
57 [label="Jump: ^foo Unit"];
58 [label="Stub" style="filled" fillcolor=gray];
59 [label="Exit block" style="filled" fillcolor=gray];
}
60 [label="Exit when branch result" style="filled" fillcolor=gray];
61 [label="Exit when"];
}
62 [label="Access variable R|<local>/x|"];
63 [label="Function call: R|/bar|(...)" style="filled" fillcolor=yellow];
64 [label="Exit block"];
}
65 [label="Exit function foo" style="filled" fillcolor=red];
}
42 -> {43};
43 -> {44};
44 -> {45};
45 -> {46};
46 -> {47};
47 -> {48};
48 -> {49};
49 -> {51 50};
50 -> {61};
51 -> {52};
52 -> {53};
53 -> {54};
54 -> {55};
55 -> {56};
56 -> {57};
57 -> {65};
57 -> {58} [style=dotted];
58 -> {59} [style=dotted];
59 -> {60} [style=dotted];
60 -> {61} [style=dotted];
61 -> {62};
62 -> {63};
63 -> {64};
64 -> {65};
}
@@ -1,20 +1,32 @@
FILE: contractsUsage.kt
@R|kotlin/contracts/ExperimentalContracts|() public final fun bar(x: R|() -> kotlin/Unit|): R|kotlin/Unit|
@R|kotlin/OptIn|(markerClass = vararg(<getClass>(Q|kotlin/contracts/ExperimentalContracts|))) public final fun bar(x: R|() -> kotlin/Unit|): R|kotlin/Unit|
[R|Contract description]
<
CallsInPlace(x, EXACTLY_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.EXACTLY_ONCE|)
}
)
}
R|<local>/x|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()
}
@R|kotlin/contracts/ExperimentalContracts|() public final fun R|() -> kotlin/Unit|.baz(): R|kotlin/Unit|
@R|kotlin/OptIn|(markerClass = vararg(<getClass>(Q|kotlin/contracts/ExperimentalContracts|))) public final fun R|() -> kotlin/Unit|.baz(): R|kotlin/Unit|
[R|Contract description]
<
CallsInPlace(this, 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|>(this@R|/baz|, Q|kotlin/contracts/InvocationKind|.R|kotlin/contracts/InvocationKind.AT_MOST_ONCE|)
}
)
}
when () {
Boolean(true) -> {
this@R|/baz|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()
@@ -22,14 +34,21 @@ FILE: contractsUsage.kt
}
}
@R|kotlin/contracts/ExperimentalContracts|() public final fun foo(x: R|() -> kotlin/Unit|, y: R|() -> kotlin/Unit|): R|kotlin/Unit|
@R|kotlin/OptIn|(markerClass = vararg(<getClass>(Q|kotlin/contracts/ExperimentalContracts|))) public final fun foo(x: R|() -> kotlin/Unit|, y: R|() -> kotlin/Unit|): R|kotlin/Unit|
[R|Contract description]
<
CallsInPlace(x, AT_LEAST_ONCE)
CallsInPlace(y, 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_LEAST_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|)
}
)
}
when () {
Boolean(true) -> {
R|<local>/x|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()
@@ -1,7 +1,7 @@
// !DUMP_CFG
import kotlin.contracts.*
@ExperimentalContracts
@OptIn(ExperimentalContracts::class)
fun bar(x: () -> Unit) {
contract {
callsInPlace(x, InvocationKind.EXACTLY_ONCE)
@@ -10,7 +10,7 @@ fun bar(x: () -> Unit) {
x.invoke()
}
@ExperimentalContracts
@OptIn(ExperimentalContracts::class)
fun (() -> Unit).baz() {
contract {
callsInPlace(this@baz, InvocationKind.AT_MOST_ONCE)
@@ -21,7 +21,7 @@ fun (() -> Unit).baz() {
}
}
@ExperimentalContracts
@OptIn(ExperimentalContracts::class)
fun foo(x: () -> Unit, y: () -> Unit) {
contract {
callsInPlace(x, InvocationKind.AT_LEAST_ONCE)
@@ -9,122 +9,136 @@ digraph exactlyOnce_kt {
subgraph cluster_1 {
color=blue
1 [label="Enter block"];
2 [label="Function call: R|<local>/block|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()" style="filled" fillcolor=yellow];
3 [label="Exit block"];
subgraph cluster_2 {
color=blue
2 [label="Enter block"];
3 [label="Exit block"];
}
4 [label="Function call: R|<local>/block|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()" style="filled" fillcolor=yellow];
5 [label="Exit block"];
}
4 [label="Exit function inlineRun" style="filled" fillcolor=red];
6 [label="Exit function inlineRun" style="filled" fillcolor=red];
}
0 -> {1};
1 -> {2};
2 -> {3};
3 -> {4};
subgraph cluster_2 {
color=red
5 [label="Enter function myRun" style="filled" fillcolor=red];
subgraph cluster_3 {
color=blue
6 [label="Enter block"];
7 [label="Function call: R|<local>/block|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()" style="filled" fillcolor=yellow];
8 [label="Exit block"];
}
9 [label="Exit function myRun" style="filled" fillcolor=red];
}
4 -> {5};
5 -> {6};
6 -> {7};
7 -> {8};
8 -> {9};
subgraph cluster_4 {
subgraph cluster_3 {
color=red
10 [label="Enter function test_1" style="filled" fillcolor=red];
subgraph cluster_5 {
15 [label="Enter function myRun" style="filled" fillcolor=red];
subgraph cluster_4 {
color=blue
11 [label="Enter block"];
12 [label="Variable declaration: lval x: R|kotlin/Int|"];
13 [label="Postponed enter to lambda"];
subgraph cluster_6 {
16 [label="Enter block"];
subgraph cluster_5 {
color=blue
20 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
subgraph cluster_7 {
color=blue
21 [label="Enter block"];
22 [label="Const: Int(1)"];
23 [label="Assignment: R|<local>/x|"];
24 [label="Exit block"];
}
25 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
17 [label="Enter block"];
18 [label="Exit block"];
}
14 [label="Postponed exit from lambda"];
15 [label="Function call: R|/inlineRun|(...)" style="filled" fillcolor=yellow];
16 [label="Access variable R|<local>/x|"];
17 [label="Function call: R|<local>/x|.R|kotlin/Int.inc|()" style="filled" fillcolor=yellow];
18 [label="Exit block"];
19 [label="Function call: R|<local>/block|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()" style="filled" fillcolor=yellow];
20 [label="Exit block"];
}
19 [label="Exit function test_1" style="filled" fillcolor=red];
21 [label="Exit function myRun" style="filled" fillcolor=red];
}
10 -> {11};
11 -> {12};
12 -> {13};
13 -> {20 15};
13 -> {14} [style=dotted];
13 -> {20} [style=dashed];
14 -> {15};
15 -> {16};
16 -> {17};
17 -> {18};
18 -> {19};
19 -> {20};
20 -> {21};
21 -> {22};
22 -> {23};
23 -> {24};
24 -> {25};
25 -> {14};
subgraph cluster_8 {
subgraph cluster_6 {
color=red
26 [label="Enter function test_2" style="filled" fillcolor=red];
subgraph cluster_9 {
30 [label="Enter function test_1" style="filled" fillcolor=red];
subgraph cluster_7 {
color=blue
27 [label="Enter block"];
28 [label="Variable declaration: lval x: R|kotlin/Int|"];
29 [label="Postponed enter to lambda"];
subgraph cluster_10 {
31 [label="Enter block"];
32 [label="Variable declaration: lval x: R|kotlin/Int|"];
33 [label="Postponed enter to lambda"];
subgraph cluster_8 {
color=blue
36 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
subgraph cluster_11 {
40 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
subgraph cluster_9 {
color=blue
37 [label="Enter block"];
38 [label="Const: Int(1)"];
39 [label="Assignment: R|<local>/x|"];
40 [label="Exit block"];
41 [label="Enter block"];
42 [label="Const: Int(1)"];
43 [label="Assignment: R|<local>/x|"];
44 [label="Exit block"];
}
41 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
45 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
}
30 [label="Postponed exit from lambda"];
31 [label="Function call: R|/myRun|(...)" style="filled" fillcolor=yellow];
32 [label="Access variable R|<local>/x|"];
33 [label="Function call: R|<local>/x|.R|kotlin/Int.inc|()" style="filled" fillcolor=yellow];
34 [label="Exit block"];
34 [label="Postponed exit from lambda"];
35 [label="Function call: R|/inlineRun|(...)" style="filled" fillcolor=yellow];
36 [label="Access variable R|<local>/x|"];
37 [label="Function call: R|<local>/x|.R|kotlin/Int.inc|()" style="filled" fillcolor=yellow];
38 [label="Exit block"];
}
35 [label="Exit function test_2" style="filled" fillcolor=red];
39 [label="Exit function test_1" style="filled" fillcolor=red];
}
26 -> {27};
27 -> {28};
28 -> {29};
29 -> {36 31};
29 -> {30} [style=dotted];
29 -> {36} [style=dashed];
30 -> {31};
31 -> {32};
32 -> {33};
33 -> {34};
33 -> {40 35};
33 -> {34} [style=dotted];
33 -> {40} [style=dashed];
34 -> {35};
35 -> {36};
36 -> {37};
37 -> {38};
38 -> {39};
39 -> {40};
40 -> {41};
41 -> {30};
41 -> {42};
42 -> {43};
43 -> {44};
44 -> {45};
45 -> {34};
subgraph cluster_10 {
color=red
46 [label="Enter function test_2" style="filled" fillcolor=red];
subgraph cluster_11 {
color=blue
47 [label="Enter block"];
48 [label="Variable declaration: lval x: R|kotlin/Int|"];
49 [label="Postponed enter to lambda"];
subgraph cluster_12 {
color=blue
56 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
subgraph cluster_13 {
color=blue
57 [label="Enter block"];
58 [label="Const: Int(1)"];
59 [label="Assignment: R|<local>/x|"];
60 [label="Exit block"];
}
61 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
}
50 [label="Postponed exit from lambda"];
51 [label="Function call: R|/myRun|(...)" style="filled" fillcolor=yellow];
52 [label="Access variable R|<local>/x|"];
53 [label="Function call: R|<local>/x|.R|kotlin/Int.inc|()" style="filled" fillcolor=yellow];
54 [label="Exit block"];
}
55 [label="Exit function test_2" style="filled" fillcolor=red];
}
46 -> {47};
47 -> {48};
48 -> {49};
49 -> {56 51};
49 -> {50} [style=dotted];
49 -> {56} [style=dashed];
50 -> {51};
51 -> {52};
52 -> {53};
53 -> {54};
54 -> {55};
56 -> {57};
57 -> {58};
58 -> {59};
59 -> {60};
60 -> {61};
61 -> {50};
}
@@ -1,20 +1,32 @@
FILE: exactlyOnce.kt
public final inline fun inlineRun(block: R|() -> kotlin/Unit|): R|kotlin/Unit|
@R|kotlin/OptIn|(markerClass = vararg(<getClass>(Q|kotlin/contracts/ExperimentalContracts|))) public final inline fun inlineRun(block: R|() -> kotlin/Unit|): R|kotlin/Unit|
[R|Contract description]
<
CallsInPlace(block, EXACTLY_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>/block|, Q|kotlin/contracts/InvocationKind|.R|kotlin/contracts/InvocationKind.EXACTLY_ONCE|)
}
)
}
R|<local>/block|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()
}
public final fun myRun(block: R|() -> kotlin/Unit|): R|kotlin/Unit|
@R|kotlin/OptIn|(markerClass = vararg(<getClass>(Q|kotlin/contracts/ExperimentalContracts|))) public final fun myRun(block: R|() -> kotlin/Unit|): R|kotlin/Unit|
[R|Contract description]
<
CallsInPlace(block, EXACTLY_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>/block|, Q|kotlin/contracts/InvocationKind|.R|kotlin/contracts/InvocationKind.EXACTLY_ONCE|)
}
)
}
R|<local>/block|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()
}
public final fun test_1(): R|kotlin/Unit| {
@@ -2,6 +2,7 @@
import kotlin.contracts.*
@OptIn(ExperimentalContracts::class)
inline fun inlineRun(block: () -> Unit) {
contract {
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
@@ -9,6 +10,7 @@ inline fun inlineRun(block: () -> Unit) {
block()
}
@OptIn(ExperimentalContracts::class)
fun myRun(block: () -> Unit) {
contract {
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
@@ -11,221 +11,222 @@ digraph flow_kt {
1 [label="Enter block"];
subgraph cluster_2 {
color=blue
2 [label="Enter when"];
subgraph cluster_3 {
color=blue
3 [label="Enter when branch condition "];
4 [label="Const: Boolean(true)"];
5 [label="Exit when branch condition"];
}
6 [label="Synthetic else branch"];
7 [label="Enter when branch result"];
2 [label="Enter block"];
3 [label="Exit block"];
}
subgraph cluster_3 {
color=blue
4 [label="Enter when"];
subgraph cluster_4 {
color=blue
8 [label="Enter block"];
9 [label="Access variable R|<local>/x|"];
10 [label="Function call: R|<local>/x|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()" style="filled" fillcolor=yellow];
11 [label="Jump: ^bar Unit"];
12 [label="Stub" style="filled" fillcolor=gray];
13 [label="Exit block" style="filled" fillcolor=gray];
5 [label="Enter when branch condition "];
6 [label="Const: Boolean(true)"];
7 [label="Exit when branch condition"];
}
14 [label="Exit when branch result" style="filled" fillcolor=gray];
15 [label="Exit when"];
8 [label="Synthetic else branch"];
9 [label="Enter when branch result"];
subgraph cluster_5 {
color=blue
10 [label="Enter block"];
11 [label="Access variable R|<local>/x|"];
12 [label="Function call: R|<local>/x|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()" style="filled" fillcolor=yellow];
13 [label="Jump: ^bar Unit"];
14 [label="Stub" style="filled" fillcolor=gray];
15 [label="Exit block" style="filled" fillcolor=gray];
}
16 [label="Exit when branch result" style="filled" fillcolor=gray];
17 [label="Exit when"];
}
16 [label="Access variable R|<local>/x|"];
17 [label="Function call: R|/bar|(...)" style="filled" fillcolor=yellow];
18 [label="Exit block"];
18 [label="Access variable R|<local>/x|"];
19 [label="Function call: R|/bar|(...)" style="filled" fillcolor=yellow];
20 [label="Exit block"];
}
19 [label="Exit function bar" style="filled" fillcolor=red];
21 [label="Exit function bar" style="filled" fillcolor=red];
}
0 -> {1};
1 -> {2};
2 -> {3};
3 -> {4};
4 -> {5};
5 -> {7 6};
6 -> {15};
7 -> {8};
8 -> {9};
5 -> {6};
6 -> {7};
7 -> {9 8};
8 -> {17};
9 -> {10};
10 -> {11};
11 -> {19};
11 -> {12} [style=dotted];
12 -> {13} [style=dotted];
11 -> {12};
12 -> {13};
13 -> {21};
13 -> {14} [style=dotted];
14 -> {15} [style=dotted];
15 -> {16};
16 -> {17};
15 -> {16} [style=dotted];
16 -> {17} [style=dotted];
17 -> {18};
18 -> {19};
19 -> {20};
20 -> {21};
subgraph cluster_5 {
subgraph cluster_6 {
color=red
20 [label="Enter function foo" style="filled" fillcolor=red];
subgraph cluster_6 {
30 [label="Enter function foo" style="filled" fillcolor=red];
subgraph cluster_7 {
color=blue
21 [label="Enter block"];
subgraph cluster_7 {
31 [label="Enter block"];
subgraph cluster_8 {
color=blue
22 [label="Enter when"];
subgraph cluster_8 {
color=blue
23 [label="Enter when branch condition "];
24 [label="Const: Boolean(true)"];
25 [label="Exit when branch condition"];
}
subgraph cluster_9 {
color=blue
26 [label="Enter when branch condition else"];
27 [label="Exit when branch condition"];
}
28 [label="Enter when branch result"];
32 [label="Enter block"];
33 [label="Exit block"];
}
subgraph cluster_9 {
color=blue
34 [label="Enter when"];
subgraph cluster_10 {
color=blue
29 [label="Enter block"];
subgraph cluster_11 {
35 [label="Enter when branch condition "];
36 [label="Const: Boolean(true)"];
37 [label="Exit when branch condition"];
}
subgraph cluster_11 {
color=blue
38 [label="Enter when branch condition else"];
39 [label="Exit when branch condition"];
}
40 [label="Enter when branch result"];
subgraph cluster_12 {
color=blue
41 [label="Enter block"];
subgraph cluster_13 {
color=blue
30 [label="Enter when"];
subgraph cluster_12 {
color=blue
31 [label="Enter when branch condition "];
32 [label="Const: Boolean(false)"];
33 [label="Exit when branch condition"];
}
subgraph cluster_13 {
color=blue
34 [label="Enter when branch condition else"];
35 [label="Exit when branch condition"];
}
36 [label="Enter when branch result"];
42 [label="Enter when"];
subgraph cluster_14 {
color=blue
37 [label="Enter block"];
38 [label="Access variable R|<local>/y|"];
39 [label="Function call: R|<local>/y|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()" style="filled" fillcolor=yellow];
40 [label="Access variable R|<local>/z|"];
41 [label="Function call: R|<local>/z|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()" style="filled" fillcolor=yellow];
42 [label="Jump: ^foo Unit"];
43 [label="Stub" style="filled" fillcolor=gray];
44 [label="Exit block" style="filled" fillcolor=gray];
43 [label="Enter when branch condition "];
44 [label="Const: Boolean(false)"];
45 [label="Exit when branch condition"];
}
45 [label="Exit when branch result" style="filled" fillcolor=gray];
46 [label="Enter when branch result"];
subgraph cluster_15 {
color=blue
47 [label="Enter block"];
48 [label="Access variable R|<local>/y|"];
49 [label="Function call: R|<local>/y|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()" style="filled" fillcolor=yellow];
50 [label="Exit block"];
46 [label="Enter when branch condition else"];
47 [label="Exit when branch condition"];
}
51 [label="Exit when branch result"];
52 [label="Exit when"];
}
53 [label="Exit block"];
}
54 [label="Exit when branch result"];
55 [label="Enter when branch result"];
subgraph cluster_16 {
color=blue
56 [label="Enter block"];
subgraph cluster_17 {
color=blue
57 [label="Enter block"];
58 [label="Const: Int(0)"];
59 [label="Const: Int(0)"];
60 [label="Function call: Int(0).R|kotlin/Int.rangeTo|(...)" style="filled" fillcolor=yellow];
61 [label="Function call: Int(0).R|kotlin/Int.rangeTo|(...).R|kotlin/ranges/IntProgression.iterator|()" style="filled" fillcolor=yellow];
62 [label="Variable declaration: lval <iterator>: R|kotlin/collections/IntIterator|"];
subgraph cluster_18 {
48 [label="Enter when branch result"];
subgraph cluster_16 {
color=blue
63 [label="Enter while loop"];
subgraph cluster_19 {
color=blue
64 [label="Enter loop condition"];
65 [label="Access variable R|<local>/<iterator>|"];
66 [label="Function call: R|<local>/<iterator>|.R|SubstitutionOverride<kotlin/collections/IntIterator.hasNext: R|kotlin/Boolean|>|()" style="filled" fillcolor=yellow];
67 [label="Exit loop condition"];
}
subgraph cluster_20 {
color=blue
68 [label="Enter loop block"];
subgraph cluster_21 {
color=blue
69 [label="Enter block"];
70 [label="Access variable R|<local>/<iterator>|"];
71 [label="Function call: R|<local>/<iterator>|.R|kotlin/collections/IntIterator.next|()" style="filled" fillcolor=yellow];
72 [label="Variable declaration: lval i: R|kotlin/Int|"];
73 [label="Access variable R|<local>/x|"];
74 [label="Function call: R|<local>/x|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()" style="filled" fillcolor=yellow];
75 [label="Exit block"];
}
76 [label="Exit loop block"];
}
77 [label="Exit whileloop"];
49 [label="Enter block"];
50 [label="Access variable R|<local>/y|"];
51 [label="Function call: R|<local>/y|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()" style="filled" fillcolor=yellow];
52 [label="Access variable R|<local>/z|"];
53 [label="Function call: R|<local>/z|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()" style="filled" fillcolor=yellow];
54 [label="Jump: ^foo Unit"];
55 [label="Stub" style="filled" fillcolor=gray];
56 [label="Exit block" style="filled" fillcolor=gray];
}
78 [label="Exit block"];
57 [label="Exit when branch result" style="filled" fillcolor=gray];
58 [label="Enter when branch result"];
subgraph cluster_17 {
color=blue
59 [label="Enter block"];
60 [label="Access variable R|<local>/y|"];
61 [label="Function call: R|<local>/y|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()" style="filled" fillcolor=yellow];
62 [label="Exit block"];
}
63 [label="Exit when branch result"];
64 [label="Exit when"];
}
79 [label="Access variable R|<local>/y|"];
80 [label="Function call: R|<local>/y|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()" style="filled" fillcolor=yellow];
81 [label="Exit block"];
65 [label="Exit block"];
}
82 [label="Exit when branch result"];
83 [label="Exit when"];
}
subgraph cluster_22 {
color=blue
84 [label="Enter do-while loop"];
subgraph cluster_23 {
66 [label="Exit when branch result"];
67 [label="Enter when branch result"];
subgraph cluster_18 {
color=blue
85 [label="Enter loop block"];
subgraph cluster_24 {
68 [label="Enter block"];
subgraph cluster_19 {
color=blue
86 [label="Enter block"];
87 [label="Access variable R|<local>/z|"];
88 [label="Function call: R|/bar|(...)" style="filled" fillcolor=yellow];
89 [label="Exit block"];
69 [label="Enter block"];
70 [label="Const: Int(0)"];
71 [label="Const: Int(0)"];
72 [label="Function call: Int(0).R|kotlin/Int.rangeTo|(...)" style="filled" fillcolor=yellow];
73 [label="Function call: Int(0).R|kotlin/Int.rangeTo|(...).R|kotlin/ranges/IntProgression.iterator|()" style="filled" fillcolor=yellow];
74 [label="Variable declaration: lval <iterator>: R|kotlin/collections/IntIterator|"];
subgraph cluster_20 {
color=blue
75 [label="Enter while loop"];
subgraph cluster_21 {
color=blue
76 [label="Enter loop condition"];
77 [label="Access variable R|<local>/<iterator>|"];
78 [label="Function call: R|<local>/<iterator>|.R|SubstitutionOverride<kotlin/collections/IntIterator.hasNext: R|kotlin/Boolean|>|()" style="filled" fillcolor=yellow];
79 [label="Exit loop condition"];
}
subgraph cluster_22 {
color=blue
80 [label="Enter loop block"];
subgraph cluster_23 {
color=blue
81 [label="Enter block"];
82 [label="Access variable R|<local>/<iterator>|"];
83 [label="Function call: R|<local>/<iterator>|.R|kotlin/collections/IntIterator.next|()" style="filled" fillcolor=yellow];
84 [label="Variable declaration: lval i: R|kotlin/Int|"];
85 [label="Access variable R|<local>/x|"];
86 [label="Function call: R|<local>/x|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()" style="filled" fillcolor=yellow];
87 [label="Exit block"];
}
88 [label="Exit loop block"];
}
89 [label="Exit whileloop"];
}
90 [label="Exit block"];
}
90 [label="Exit loop block"];
91 [label="Access variable R|<local>/y|"];
92 [label="Function call: R|<local>/y|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()" style="filled" fillcolor=yellow];
93 [label="Exit block"];
}
94 [label="Exit when branch result"];
95 [label="Exit when"];
}
subgraph cluster_24 {
color=blue
96 [label="Enter do-while loop"];
subgraph cluster_25 {
color=blue
91 [label="Enter loop condition"];
92 [label="Const: Boolean(true)"];
93 [label="Exit loop condition"];
97 [label="Enter loop block"];
subgraph cluster_26 {
color=blue
98 [label="Enter block"];
99 [label="Access variable R|<local>/z|"];
100 [label="Function call: R|/bar|(...)" style="filled" fillcolor=yellow];
101 [label="Exit block"];
}
102 [label="Exit loop block"];
}
94 [label="Exit do-whileloop" style="filled" fillcolor=gray];
subgraph cluster_27 {
color=blue
103 [label="Enter loop condition"];
104 [label="Const: Boolean(true)"];
105 [label="Exit loop condition"];
}
106 [label="Exit do-whileloop" style="filled" fillcolor=gray];
}
95 [label="Exit block" style="filled" fillcolor=gray];
107 [label="Exit block" style="filled" fillcolor=gray];
}
96 [label="Exit function foo" style="filled" fillcolor=red];
108 [label="Exit function foo" style="filled" fillcolor=red];
}
20 -> {21};
21 -> {22};
22 -> {23};
23 -> {24};
24 -> {25};
25 -> {55 26};
26 -> {27};
27 -> {28};
28 -> {29};
29 -> {30};
30 -> {31};
31 -> {32};
32 -> {33};
33 -> {46 34};
33 -> {34};
34 -> {35};
35 -> {36};
36 -> {37};
37 -> {38};
37 -> {67 38};
38 -> {39};
39 -> {40};
40 -> {41};
41 -> {42};
42 -> {96};
42 -> {43} [style=dotted];
43 -> {44} [style=dotted];
44 -> {45} [style=dotted];
45 -> {52} [style=dotted];
42 -> {43};
43 -> {44};
44 -> {45};
45 -> {58 46};
46 -> {47};
47 -> {48};
48 -> {49};
@@ -234,10 +235,11 @@ digraph flow_kt {
51 -> {52};
52 -> {53};
53 -> {54};
54 -> {83};
55 -> {56};
56 -> {57};
57 -> {58};
54 -> {108};
54 -> {55} [style=dotted];
55 -> {56} [style=dotted];
56 -> {57} [style=dotted];
57 -> {64} [style=dotted];
58 -> {59};
59 -> {60};
60 -> {61};
@@ -246,8 +248,8 @@ digraph flow_kt {
63 -> {64};
64 -> {65};
65 -> {66};
66 -> {67};
67 -> {77 68};
66 -> {95};
67 -> {68};
68 -> {69};
69 -> {70};
70 -> {71};
@@ -256,10 +258,10 @@ digraph flow_kt {
73 -> {74};
74 -> {75};
75 -> {76};
76 -> {64} [color=green style=dashed];
76 -> {77};
77 -> {78};
78 -> {79};
79 -> {80};
79 -> {89 80};
80 -> {81};
81 -> {82};
82 -> {83};
@@ -268,14 +270,26 @@ digraph flow_kt {
85 -> {86};
86 -> {87};
87 -> {88};
88 -> {89};
88 -> {76} [color=green style=dashed];
89 -> {90};
90 -> {91};
91 -> {92};
92 -> {93};
93 -> {94} [style=dotted];
93 -> {85} [color=green style=dashed];
94 -> {95} [style=dotted];
95 -> {96} [style=dotted];
93 -> {94};
94 -> {95};
95 -> {96};
96 -> {97};
97 -> {98};
98 -> {99};
99 -> {100};
100 -> {101};
101 -> {102};
102 -> {103};
103 -> {104};
104 -> {105};
105 -> {106} [style=dotted];
105 -> {97} [color=green style=dashed];
106 -> {107} [style=dotted];
107 -> {108} [style=dotted];
}
@@ -1,11 +1,17 @@
FILE: flow.kt
@R|kotlin/contracts/ExperimentalContracts|() public final fun bar(x: R|() -> kotlin/Unit|): R|kotlin/Unit|
@R|kotlin/OptIn|(markerClass = vararg(<getClass>(Q|kotlin/contracts/ExperimentalContracts|))) public final fun bar(x: R|() -> kotlin/Unit|): R|kotlin/Unit|
[R|Contract description]
<
CallsInPlace(x, EXACTLY_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.EXACTLY_ONCE|)
}
)
}
when () {
Boolean(true) -> {
R|<local>/x|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()
@@ -15,7 +21,7 @@ FILE: flow.kt
R|/bar|(R|<local>/x|)
}
@R|kotlin/contracts/ExperimentalContracts|() public final fun foo(x: R|() -> kotlin/Unit|, y: R|() -> kotlin/Unit|, z: R|() -> kotlin/Unit|): R|kotlin/Unit|
@R|kotlin/OptIn|(markerClass = vararg(<getClass>(Q|kotlin/contracts/ExperimentalContracts|))) public final fun foo(x: R|() -> kotlin/Unit|, y: R|() -> kotlin/Unit|, z: R|() -> kotlin/Unit|): R|kotlin/Unit|
[R|Contract description]
<
CallsInPlace(x, UNKNOWN)
@@ -23,7 +29,15 @@ FILE: flow.kt
CallsInPlace(z, AT_LEAST_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.UNKNOWN|)
this@R|special/anonymous|.R|kotlin/contracts/ContractBuilder.callsInPlace|<R|kotlin/Unit|>(R|<local>/y|, Q|kotlin/contracts/InvocationKind|.R|kotlin/contracts/InvocationKind.EXACTLY_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_LEAST_ONCE|)
}
)
}
when () {
Boolean(true) -> {
{
@@ -1,7 +1,7 @@
// !DUMP_CFG
import kotlin.contracts.*
@ExperimentalContracts
@OptIn(ExperimentalContracts::class)
fun bar(x: () -> Unit) {
contract {
callsInPlace(x, InvocationKind.EXACTLY_ONCE)
@@ -15,7 +15,7 @@ fun bar(x: () -> Unit) {
bar(x)
}
@ExperimentalContracts
@OptIn(ExperimentalContracts::class)
fun foo(x: () -> Unit, y: () -> Unit, z: () -> Unit) {
contract {
callsInPlace(x, InvocationKind.UNKNOWN)
@@ -11,80 +11,94 @@ digraph inPlaceLambda_kt {
1 [label="Enter block"];
subgraph cluster_2 {
color=blue
2 [label="Enter when"];
subgraph cluster_3 {
color=blue
3 [label="Enter when branch condition "];
4 [label="Const: Boolean(true)"];
5 [label="Exit when branch condition"];
}
6 [label="Synthetic else branch"];
7 [label="Enter when branch result"];
2 [label="Enter block"];
3 [label="Exit block"];
}
subgraph cluster_3 {
color=blue
4 [label="Enter when"];
subgraph cluster_4 {
color=blue
8 [label="Enter block"];
9 [label="Function call: R|<local>/x|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()" style="filled" fillcolor=yellow];
10 [label="Exit block"];
5 [label="Enter when branch condition "];
6 [label="Const: Boolean(true)"];
7 [label="Exit when branch condition"];
}
11 [label="Exit when branch result"];
12 [label="Exit when"];
8 [label="Synthetic else branch"];
9 [label="Enter when branch result"];
subgraph cluster_5 {
color=blue
10 [label="Enter block"];
11 [label="Function call: R|<local>/x|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()" style="filled" fillcolor=yellow];
12 [label="Exit block"];
}
13 [label="Exit when branch result"];
14 [label="Exit when"];
}
13 [label="Exit block"];
15 [label="Exit block"];
}
14 [label="Exit function bar" style="filled" fillcolor=red];
16 [label="Exit function bar" style="filled" fillcolor=red];
}
0 -> {1};
1 -> {2};
2 -> {3};
3 -> {4};
4 -> {5};
5 -> {7 6};
6 -> {12};
7 -> {8};
8 -> {9};
5 -> {6};
6 -> {7};
7 -> {9 8};
8 -> {14};
9 -> {10};
10 -> {11};
11 -> {12};
12 -> {13};
13 -> {14};
subgraph cluster_5 {
color=red
15 [label="Enter function foo" style="filled" fillcolor=red];
subgraph cluster_6 {
color=blue
16 [label="Enter block"];
17 [label="Function call: R|<local>/x|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()" style="filled" fillcolor=yellow];
18 [label="Postponed enter to lambda"];
subgraph cluster_7 {
color=blue
23 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
subgraph cluster_8 {
color=blue
24 [label="Enter block"];
25 [label="Function call: R|<local>/x|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()" style="filled" fillcolor=yellow];
26 [label="Exit block"];
}
27 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
}
19 [label="Postponed exit from lambda"];
20 [label="Function call: R|/bar|(...)" style="filled" fillcolor=yellow];
21 [label="Exit block"];
}
22 [label="Exit function foo" style="filled" fillcolor=red];
}
14 -> {15};
15 -> {16};
16 -> {17};
17 -> {18};
18 -> {19 23 20};
18 -> {23} [style=dashed];
19 -> {20};
20 -> {21};
21 -> {22};
23 -> {24};
24 -> {25};
subgraph cluster_6 {
color=red
25 [label="Enter function foo" style="filled" fillcolor=red];
subgraph cluster_7 {
color=blue
26 [label="Enter block"];
subgraph cluster_8 {
color=blue
27 [label="Enter block"];
28 [label="Exit block"];
}
29 [label="Function call: R|<local>/x|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()" style="filled" fillcolor=yellow];
30 [label="Postponed enter to lambda"];
subgraph cluster_9 {
color=blue
35 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
subgraph cluster_10 {
color=blue
36 [label="Enter block"];
37 [label="Function call: R|<local>/x|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()" style="filled" fillcolor=yellow];
38 [label="Exit block"];
}
39 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
}
31 [label="Postponed exit from lambda"];
32 [label="Function call: R|/bar|(...)" style="filled" fillcolor=yellow];
33 [label="Exit block"];
}
34 [label="Exit function foo" style="filled" fillcolor=red];
}
25 -> {26};
26 -> {27};
27 -> {19};
27 -> {28};
28 -> {29};
29 -> {30};
30 -> {31 35 32};
30 -> {35} [style=dashed];
31 -> {32};
32 -> {33};
33 -> {34};
35 -> {36};
36 -> {37};
37 -> {38};
38 -> {39};
39 -> {31};
}
@@ -1,11 +1,17 @@
FILE: inPlaceLambda.kt
@R|kotlin/contracts/ExperimentalContracts|() public final fun bar(x: R|() -> kotlin/Unit|): R|kotlin/Unit|
@R|kotlin/OptIn|(markerClass = vararg(<getClass>(Q|kotlin/contracts/ExperimentalContracts|))) public final fun bar(x: R|() -> kotlin/Unit|): R|kotlin/Unit|
[R|Contract description]
<
CallsInPlace(x, 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|)
}
)
}
when () {
Boolean(true) -> {
R|<local>/x|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()
@@ -13,13 +19,19 @@ FILE: inPlaceLambda.kt
}
}
@R|kotlin/contracts/ExperimentalContracts|() public final fun foo(x: R|() -> kotlin/Unit|): R|kotlin/Unit|
@R|kotlin/OptIn|(markerClass = vararg(<getClass>(Q|kotlin/contracts/ExperimentalContracts|))) public final fun foo(x: R|() -> kotlin/Unit|): R|kotlin/Unit|
[R|Contract description]
<
CallsInPlace(x, AT_LEAST_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_LEAST_ONCE|)
}
)
}
R|<local>/x|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()
R|/bar|(<L> = bar@fun <anonymous>(): R|kotlin/Unit| <inline=NoInline, kind=AT_MOST_ONCE> {
R|<local>/x|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()
@@ -1,7 +1,7 @@
// !DUMP_CFG
import kotlin.contracts.*
@ExperimentalContracts
@OptIn(ExperimentalContracts::class)
fun bar(x: () -> Unit) {
contract {
callsInPlace(x, InvocationKind.AT_MOST_ONCE)
@@ -12,7 +12,7 @@ fun bar(x: () -> Unit) {
}
}
@ExperimentalContracts
@OptIn(ExperimentalContracts::class)
fun foo(x: () -> Unit) {
contract {
callsInPlace(x, InvocationKind.AT_LEAST_ONCE)
@@ -9,62 +9,64 @@ digraph simple_kt {
subgraph cluster_1 {
color=blue
1 [label="Enter block"];
2 [label="Access variable R|<local>/x|"];
3 [label="Function call: R|<local>/x|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()" style="filled" fillcolor=yellow];
4 [label="Exit block"];
subgraph cluster_2 {
color=blue
2 [label="Enter block"];
3 [label="Exit block"];
}
4 [label="Access variable R|<local>/x|"];
5 [label="Function call: R|<local>/x|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()" style="filled" fillcolor=yellow];
6 [label="Exit block"];
}
5 [label="Exit function bar" style="filled" fillcolor=red];
7 [label="Exit function bar" style="filled" fillcolor=red];
}
0 -> {1};
1 -> {2};
2 -> {3};
3 -> {4};
4 -> {5};
subgraph cluster_2 {
color=red
6 [label="Enter function foo" style="filled" fillcolor=red];
subgraph cluster_3 {
color=blue
7 [label="Enter block"];
8 [label="Access variable R|<local>/x|"];
9 [label="Function call: R|<local>/x|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()" style="filled" fillcolor=yellow];
subgraph cluster_4 {
color=blue
10 [label="Enter when"];
subgraph cluster_5 {
color=blue
11 [label="Enter when branch condition "];
12 [label="Const: Boolean(true)"];
13 [label="Exit when branch condition"];
}
14 [label="Synthetic else branch"];
15 [label="Enter when branch result"];
subgraph cluster_6 {
color=blue
16 [label="Enter block"];
17 [label="Function call: R|<local>/y|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()" style="filled" fillcolor=yellow];
18 [label="Exit block"];
}
19 [label="Exit when branch result"];
20 [label="Exit when"];
}
21 [label="Access variable R|<local>/z|"];
22 [label="Function call: R|/bar|(...)" style="filled" fillcolor=yellow];
23 [label="Exit block"];
}
24 [label="Exit function foo" style="filled" fillcolor=red];
}
5 -> {6};
6 -> {7};
7 -> {8};
8 -> {9};
9 -> {10};
10 -> {11};
11 -> {12};
12 -> {13};
13 -> {15 14};
14 -> {20};
15 -> {16};
subgraph cluster_3 {
color=red
16 [label="Enter function foo" style="filled" fillcolor=red];
subgraph cluster_4 {
color=blue
17 [label="Enter block"];
subgraph cluster_5 {
color=blue
18 [label="Enter block"];
19 [label="Exit block"];
}
20 [label="Access variable R|<local>/x|"];
21 [label="Function call: R|<local>/x|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()" style="filled" fillcolor=yellow];
subgraph cluster_6 {
color=blue
22 [label="Enter when"];
subgraph cluster_7 {
color=blue
23 [label="Enter when branch condition "];
24 [label="Const: Boolean(true)"];
25 [label="Exit when branch condition"];
}
26 [label="Synthetic else branch"];
27 [label="Enter when branch result"];
subgraph cluster_8 {
color=blue
28 [label="Enter block"];
29 [label="Function call: R|<local>/y|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()" style="filled" fillcolor=yellow];
30 [label="Exit block"];
}
31 [label="Exit when branch result"];
32 [label="Exit when"];
}
33 [label="Access variable R|<local>/z|"];
34 [label="Function call: R|/bar|(...)" style="filled" fillcolor=yellow];
35 [label="Exit block"];
}
36 [label="Exit function foo" style="filled" fillcolor=red];
}
16 -> {17};
17 -> {18};
18 -> {19};
@@ -73,5 +75,17 @@ digraph simple_kt {
21 -> {22};
22 -> {23};
23 -> {24};
24 -> {25};
25 -> {27 26};
26 -> {32};
27 -> {28};
28 -> {29};
29 -> {30};
30 -> {31};
31 -> {32};
32 -> {33};
33 -> {34};
34 -> {35};
35 -> {36};
}
@@ -1,14 +1,20 @@
FILE: simple.kt
@R|kotlin/contracts/ExperimentalContracts|() public final fun bar(x: R|() -> kotlin/Unit|): R|kotlin/Unit|
@R|kotlin/OptIn|(markerClass = vararg(<getClass>(Q|kotlin/contracts/ExperimentalContracts|))) public final fun bar(x: R|() -> kotlin/Unit|): R|kotlin/Unit|
[R|Contract description]
<
CallsInPlace(x, EXACTLY_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.EXACTLY_ONCE|)
}
)
}
R|<local>/x|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()
}
@R|kotlin/contracts/ExperimentalContracts|() public final fun foo(x: R|() -> kotlin/Unit|, y: R|() -> kotlin/Unit|, z: R|() -> kotlin/Unit|): R|kotlin/Unit|
@R|kotlin/OptIn|(markerClass = vararg(<getClass>(Q|kotlin/contracts/ExperimentalContracts|))) public final fun foo(x: R|() -> kotlin/Unit|, y: R|() -> kotlin/Unit|, z: R|() -> kotlin/Unit|): R|kotlin/Unit|
[R|Contract description]
<
CallsInPlace(x, EXACTLY_ONCE)
@@ -16,7 +22,15 @@ FILE: simple.kt
CallsInPlace(z, EXACTLY_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.EXACTLY_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.EXACTLY_ONCE|)
}
)
}
R|<local>/x|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()
when () {
Boolean(true) -> {
@@ -1,7 +1,7 @@
// !DUMP_CFG
import kotlin.contracts.*
@ExperimentalContracts
@OptIn(ExperimentalContracts::class)
fun bar(x: () -> Unit) {
contract {
callsInPlace(x, InvocationKind.EXACTLY_ONCE)
@@ -10,7 +10,7 @@ fun bar(x: () -> Unit) {
x.invoke()
}
@ExperimentalContracts
@OptIn(ExperimentalContracts::class)
fun foo(x: () -> Unit, y: () -> Unit, z: () -> Unit) {
contract {
callsInPlace(x, InvocationKind.EXACTLY_ONCE)
@@ -9,122 +9,136 @@ digraph unknown_kt {
subgraph cluster_1 {
color=blue
1 [label="Enter block"];
2 [label="Function call: R|<local>/block|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()" style="filled" fillcolor=yellow];
3 [label="Exit block"];
subgraph cluster_2 {
color=blue
2 [label="Enter block"];
3 [label="Exit block"];
}
4 [label="Function call: R|<local>/block|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()" style="filled" fillcolor=yellow];
5 [label="Exit block"];
}
4 [label="Exit function inlineRun" style="filled" fillcolor=red];
6 [label="Exit function inlineRun" style="filled" fillcolor=red];
}
0 -> {1};
1 -> {2};
2 -> {3};
3 -> {4};
subgraph cluster_2 {
color=red
5 [label="Enter function myRun" style="filled" fillcolor=red];
subgraph cluster_3 {
color=blue
6 [label="Enter block"];
7 [label="Function call: R|<local>/block|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()" style="filled" fillcolor=yellow];
8 [label="Exit block"];
}
9 [label="Exit function myRun" style="filled" fillcolor=red];
}
4 -> {5};
5 -> {6};
6 -> {7};
7 -> {8};
8 -> {9};
subgraph cluster_4 {
subgraph cluster_3 {
color=red
10 [label="Enter function test_1" style="filled" fillcolor=red];
subgraph cluster_5 {
15 [label="Enter function myRun" style="filled" fillcolor=red];
subgraph cluster_4 {
color=blue
11 [label="Enter block"];
12 [label="Variable declaration: lval x: R|kotlin/Int|"];
13 [label="Postponed enter to lambda"];
subgraph cluster_6 {
16 [label="Enter block"];
subgraph cluster_5 {
color=blue
20 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
subgraph cluster_7 {
color=blue
21 [label="Enter block"];
22 [label="Const: Int(1)"];
23 [label="Assignment: R|<local>/x|"];
24 [label="Exit block"];
}
25 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
17 [label="Enter block"];
18 [label="Exit block"];
}
14 [label="Postponed exit from lambda"];
15 [label="Function call: R|/inlineRun|(...)" style="filled" fillcolor=yellow];
16 [label="Access variable R|<local>/x|"];
17 [label="Function call: R|<local>/x|.R|kotlin/Int.inc|()" style="filled" fillcolor=yellow];
18 [label="Exit block"];
19 [label="Function call: R|<local>/block|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()" style="filled" fillcolor=yellow];
20 [label="Exit block"];
}
19 [label="Exit function test_1" style="filled" fillcolor=red];
21 [label="Exit function myRun" style="filled" fillcolor=red];
}
10 -> {11};
11 -> {12};
12 -> {13};
13 -> {14 20 15};
13 -> {20} [style=dashed];
14 -> {15};
14 -> {13} [color=green style=dashed];
15 -> {16};
16 -> {17};
17 -> {18};
18 -> {19};
19 -> {20};
20 -> {21};
21 -> {22};
22 -> {23};
23 -> {24};
24 -> {25};
25 -> {14};
subgraph cluster_8 {
subgraph cluster_6 {
color=red
26 [label="Enter function test_2" style="filled" fillcolor=red];
subgraph cluster_9 {
30 [label="Enter function test_1" style="filled" fillcolor=red];
subgraph cluster_7 {
color=blue
27 [label="Enter block"];
28 [label="Variable declaration: lval x: R|kotlin/Int|"];
29 [label="Postponed enter to lambda"];
subgraph cluster_10 {
31 [label="Enter block"];
32 [label="Variable declaration: lval x: R|kotlin/Int|"];
33 [label="Postponed enter to lambda"];
subgraph cluster_8 {
color=blue
36 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
subgraph cluster_11 {
40 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
subgraph cluster_9 {
color=blue
37 [label="Enter block"];
38 [label="Const: Int(1)"];
39 [label="Assignment: R|<local>/x|"];
40 [label="Exit block"];
41 [label="Enter block"];
42 [label="Const: Int(1)"];
43 [label="Assignment: R|<local>/x|"];
44 [label="Exit block"];
}
41 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
45 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
}
30 [label="Postponed exit from lambda"];
31 [label="Function call: R|/myRun|(...)" style="filled" fillcolor=yellow];
32 [label="Access variable R|<local>/x|"];
33 [label="Function call: R|<local>/x|.R|kotlin/Int.inc|()" style="filled" fillcolor=yellow];
34 [label="Exit block"];
34 [label="Postponed exit from lambda"];
35 [label="Function call: R|/inlineRun|(...)" style="filled" fillcolor=yellow];
36 [label="Access variable R|<local>/x|"];
37 [label="Function call: R|<local>/x|.R|kotlin/Int.inc|()" style="filled" fillcolor=yellow];
38 [label="Exit block"];
}
35 [label="Exit function test_2" style="filled" fillcolor=red];
39 [label="Exit function test_1" style="filled" fillcolor=red];
}
26 -> {27};
27 -> {28};
28 -> {29};
29 -> {30 36 31};
29 -> {36} [style=dashed];
30 -> {31};
30 -> {29} [color=green style=dashed];
31 -> {32};
32 -> {33};
33 -> {34};
33 -> {34 40 35};
33 -> {40} [style=dashed];
34 -> {35};
34 -> {33} [color=green style=dashed];
35 -> {36};
36 -> {37};
37 -> {38};
38 -> {39};
39 -> {40};
40 -> {41};
41 -> {30};
41 -> {42};
42 -> {43};
43 -> {44};
44 -> {45};
45 -> {34};
subgraph cluster_10 {
color=red
46 [label="Enter function test_2" style="filled" fillcolor=red];
subgraph cluster_11 {
color=blue
47 [label="Enter block"];
48 [label="Variable declaration: lval x: R|kotlin/Int|"];
49 [label="Postponed enter to lambda"];
subgraph cluster_12 {
color=blue
56 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
subgraph cluster_13 {
color=blue
57 [label="Enter block"];
58 [label="Const: Int(1)"];
59 [label="Assignment: R|<local>/x|"];
60 [label="Exit block"];
}
61 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
}
50 [label="Postponed exit from lambda"];
51 [label="Function call: R|/myRun|(...)" style="filled" fillcolor=yellow];
52 [label="Access variable R|<local>/x|"];
53 [label="Function call: R|<local>/x|.R|kotlin/Int.inc|()" style="filled" fillcolor=yellow];
54 [label="Exit block"];
}
55 [label="Exit function test_2" style="filled" fillcolor=red];
}
46 -> {47};
47 -> {48};
48 -> {49};
49 -> {50 56 51};
49 -> {56} [style=dashed];
50 -> {51};
50 -> {49} [color=green style=dashed];
51 -> {52};
52 -> {53};
53 -> {54};
54 -> {55};
56 -> {57};
57 -> {58};
58 -> {59};
59 -> {60};
60 -> {61};
61 -> {50};
}
@@ -1,20 +1,32 @@
FILE: unknown.kt
public final inline fun inlineRun(block: R|() -> kotlin/Unit|): R|kotlin/Unit|
@R|kotlin/OptIn|(markerClass = vararg(<getClass>(Q|kotlin/contracts/ExperimentalContracts|))) public final inline fun inlineRun(block: R|() -> kotlin/Unit|): R|kotlin/Unit|
[R|Contract description]
<
CallsInPlace(block, UNKNOWN)
>
{
[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>/block|, Q|kotlin/contracts/InvocationKind|.R|kotlin/contracts/InvocationKind.UNKNOWN|)
}
)
}
R|<local>/block|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()
}
public final fun myRun(block: R|() -> kotlin/Unit|): R|kotlin/Unit|
@R|kotlin/OptIn|(markerClass = vararg(<getClass>(Q|kotlin/contracts/ExperimentalContracts|))) public final fun myRun(block: R|() -> kotlin/Unit|): R|kotlin/Unit|
[R|Contract description]
<
CallsInPlace(block, UNKNOWN)
>
{
[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>/block|, Q|kotlin/contracts/InvocationKind|.R|kotlin/contracts/InvocationKind.UNKNOWN|)
}
)
}
R|<local>/block|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()
}
public final fun test_1(): R|kotlin/Unit| {
@@ -2,6 +2,7 @@
import kotlin.contracts.*
@OptIn(ExperimentalContracts::class)
inline fun inlineRun(block: () -> Unit) {
contract {
callsInPlace(block, InvocationKind.UNKNOWN)
@@ -9,6 +10,7 @@ inline fun inlineRun(block: () -> Unit) {
block()
}
@OptIn(ExperimentalContracts::class)
fun myRun(block: () -> Unit) {
contract {
callsInPlace(block, InvocationKind.UNKNOWN)
@@ -1,11 +1,17 @@
FILE: booleanOperators.kt
public final fun myRequire(b: R|kotlin/Boolean|): R|kotlin/Unit|
@R|kotlin/OptIn|(markerClass = vararg(<getClass>(Q|kotlin/contracts/ExperimentalContracts|))) public final fun myRequire(b: R|kotlin/Boolean|): R|kotlin/Unit|
[R|Contract description]
<
Returns(WILDCARD) -> b
>
{
[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>/b|)
}
)
}
when () {
R|<local>/b|.R|kotlin/Boolean.not|() -> {
throw R|java/lang/IllegalStateException.IllegalStateException|()
@@ -13,13 +19,19 @@ FILE: booleanOperators.kt
}
}
public final fun myRequireAnd(b1: R|kotlin/Boolean|, b2: R|kotlin/Boolean|): R|kotlin/Unit|
@R|kotlin/OptIn|(markerClass = vararg(<getClass>(Q|kotlin/contracts/ExperimentalContracts|))) public final fun myRequireAnd(b1: R|kotlin/Boolean|, b2: R|kotlin/Boolean|): R|kotlin/Unit|
[R|Contract description]
<
Returns(WILDCARD) -> b1 && b2
>
{
[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>/b1| && R|<local>/b2|)
}
)
}
when () {
R|<local>/b1| && R|<local>/b2|.R|kotlin/Boolean.not|() -> {
throw R|java/lang/IllegalStateException.IllegalStateException|()
@@ -27,13 +39,19 @@ FILE: booleanOperators.kt
}
}
public final fun myRequireOr(b1: R|kotlin/Boolean|, b2: R|kotlin/Boolean|): R|kotlin/Unit|
@R|kotlin/OptIn|(markerClass = vararg(<getClass>(Q|kotlin/contracts/ExperimentalContracts|))) public final fun myRequireOr(b1: R|kotlin/Boolean|, b2: R|kotlin/Boolean|): R|kotlin/Unit|
[R|Contract description]
<
Returns(WILDCARD) -> b1 || b2
>
{
[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>/b1| || R|<local>/b2|)
}
)
}
when () {
R|<local>/b1| || R|<local>/b2|.R|kotlin/Boolean.not|() -> {
throw R|java/lang/IllegalStateException.IllegalStateException|()
@@ -41,13 +59,19 @@ FILE: booleanOperators.kt
}
}
public final fun myRequireNot(b: R|kotlin/Boolean|): R|kotlin/Unit|
@R|kotlin/OptIn|(markerClass = vararg(<getClass>(Q|kotlin/contracts/ExperimentalContracts|))) public final fun myRequireNot(b: R|kotlin/Boolean|): R|kotlin/Unit|
[R|Contract description]
<
Returns(WILDCARD) -> !b
>
{
[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>/b|.R|kotlin/Boolean.not|())
}
)
}
when () {
R|<local>/b| -> {
throw R|java/lang/IllegalStateException.IllegalStateException|()
@@ -1,5 +1,6 @@
import kotlin.contracts.*
@OptIn(ExperimentalContracts::class)
fun myRequire(b: Boolean) {
contract {
returns() implies (b)
@@ -7,6 +8,7 @@ fun myRequire(b: Boolean) {
if (!b) throw IllegalStateException()
}
@OptIn(ExperimentalContracts::class)
fun myRequireAnd(b1: Boolean, b2: Boolean) {
contract {
returns() implies (b1 && b2)
@@ -14,6 +16,7 @@ fun myRequireAnd(b1: Boolean, b2: Boolean) {
if (!(b1 && b2)) throw IllegalStateException()
}
@OptIn(ExperimentalContracts::class)
fun myRequireOr(b1: Boolean, b2: Boolean) {
contract {
returns() implies (b1 || b2)
@@ -21,6 +24,7 @@ fun myRequireOr(b1: Boolean, b2: Boolean) {
if (!(b1 || b2)) throw IllegalStateException()
}
@OptIn(ExperimentalContracts::class)
fun myRequireNot(b: Boolean) {
contract {
returns() implies (!b)
@@ -5,25 +5,43 @@ FILE: conditionLogic.kt
Returns(NOT_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.returnsNotNull|().R|kotlin/contracts/SimpleEffect.implies|(==(R|<local>/x|, Null(null)).R|kotlin/Boolean.not|())
}
)
}
^test1 R|<local>/x|
}
@R|kotlin/OptIn|(markerClass = vararg(<getClass>(Q|kotlin/contracts/ExperimentalContracts|))) public final fun test2(x: R|kotlin/String?|): R|kotlin/Any?|
[R|Contract description]
<
Returns(NOT_NULL) -> x is kotlin/String && x != null
Returns(NOT_NULL) -> x is kotlin/String
>
{
[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.returnsNotNull|().R|kotlin/contracts/SimpleEffect.implies|((R|<local>/x| is R|kotlin/String|))
}
)
}
^test2 R|<local>/x|
}
@R|kotlin/OptIn|(markerClass = vararg(<getClass>(Q|kotlin/contracts/ExperimentalContracts|))) public final fun test3(x: R|kotlin/String?|): R|kotlin/Any?|
[R|Contract description]
<
Returns(NOT_NULL) -> x is kotlin/String? || x is kotlin/Any?
Returns(NOT_NULL) -> x !is kotlin/String
>
{
[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.returnsNotNull|().R|kotlin/contracts/SimpleEffect.implies|((R|<local>/x| !is R|kotlin/String|))
}
)
}
^test3 R|<local>/x|
}
@R|kotlin/OptIn|(markerClass = vararg(<getClass>(Q|kotlin/contracts/ExperimentalContracts|))) public final fun test4(x: R|kotlin/String?|, y: R|kotlin/String?|): R|kotlin/Any?|
@@ -32,7 +50,13 @@ FILE: conditionLogic.kt
Returns(TRUE) -> x != null && y != 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|(!=(R|<local>/x|, Null(null)) && !=(R|<local>/y|, Null(null)))
}
)
}
^test4 !=(R|<local>/x|, Null(null)) && !=(R|<local>/y|, Null(null))
}
@R|kotlin/OptIn|(markerClass = vararg(<getClass>(Q|kotlin/contracts/ExperimentalContracts|))) public final fun test5(x: R|kotlin/Any?|): R|kotlin/Any?|
@@ -41,7 +65,13 @@ FILE: conditionLogic.kt
Returns(TRUE) -> x != null || x is kotlin/Any
>
{
[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|(!=(R|<local>/x|, Null(null)) || (R|<local>/x| is R|kotlin/Any|))
}
)
}
^test5 !=(R|<local>/x|, Null(null))
}
@R|kotlin/OptIn|(markerClass = vararg(<getClass>(Q|kotlin/contracts/ExperimentalContracts|))) public final fun test6(x: R|kotlin/Any?|): R|kotlin/Any?|
@@ -50,7 +80,13 @@ FILE: conditionLogic.kt
Returns(TRUE) -> x is kotlin/String? && 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|(Boolean(true)).R|kotlin/contracts/SimpleEffect.implies|((R|<local>/x| is R|kotlin/String?|) && !=(R|<local>/x|, Null(null)))
}
)
}
^test6 (R|<local>/x| is R|kotlin/String|)
}
@R|kotlin/OptIn|(markerClass = vararg(<getClass>(Q|kotlin/contracts/ExperimentalContracts|))) public final fun test7(x: R|kotlin/Any?|): R|kotlin/Any?|
@@ -59,7 +95,13 @@ FILE: conditionLogic.kt
Returns(TRUE) -> x is kotlin/String? && x != null || x is kotlin/Int
>
{
[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|((R|<local>/x| is R|kotlin/String?|) && !=(R|<local>/x|, Null(null)) || (R|<local>/x| is R|kotlin/Int|))
}
)
}
^test7 (R|<local>/x| is R|kotlin/String|)
}
@R|kotlin/OptIn|(markerClass = vararg(<getClass>(Q|kotlin/contracts/ExperimentalContracts|))) public final fun test8(x: R|kotlin/Any?|): R|kotlin/Any?|
@@ -68,7 +110,13 @@ FILE: conditionLogic.kt
Returns(TRUE) -> x is kotlin/String || x is kotlin/Int
>
{
[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|((R|<local>/x| is R|kotlin/String|) || (R|<local>/x| is R|kotlin/Int|))
}
)
}
^test8 (R|<local>/x| is R|kotlin/String|) || (R|<local>/x| is R|kotlin/Int|)
}
@R|kotlin/OptIn|(markerClass = vararg(<getClass>(Q|kotlin/contracts/ExperimentalContracts|))) public final fun test9(x: R|kotlin/Any?|): R|kotlin/Any?|
@@ -77,7 +125,13 @@ FILE: conditionLogic.kt
Returns(TRUE) -> x is kotlin/String || x is kotlin/Int
>
{
[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|((R|<local>/x| is R|kotlin/String|) || (R|<local>/x| is R|kotlin/Int|))
}
)
}
when () {
(R|<local>/x| is R|kotlin/String|) -> {
^test9 Boolean(true)
@@ -92,7 +146,13 @@ FILE: conditionLogic.kt
Returns(TRUE) -> x is kotlin/Comparable<*> || x is kotlin/CharSequence
>
{
[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|((R|<local>/x| is R|kotlin/Comparable<*>|) || (R|<local>/x| is R|kotlin/CharSequence|))
}
)
}
^test10 (R|<local>/x| is R|kotlin/String|)
}
@R|kotlin/OptIn|(markerClass = vararg(<getClass>(Q|kotlin/contracts/ExperimentalContracts|))) public final fun test11(x: R|kotlin/Any?|): R|kotlin/Any?|
@@ -101,7 +161,13 @@ FILE: conditionLogic.kt
Returns(TRUE) -> x is kotlin/Comparable<*> && x is kotlin/CharSequence
>
{
[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|((R|<local>/x| is R|kotlin/Comparable<*>|) && (R|<local>/x| is R|kotlin/CharSequence|))
}
)
}
^test11 (R|<local>/x| is R|kotlin/String|)
}
@R|kotlin/OptIn|(markerClass = vararg(<getClass>(Q|kotlin/contracts/ExperimentalContracts|))) public final fun test12(x: R|kotlin/Any?|): R|kotlin/Any?|
@@ -110,7 +176,13 @@ FILE: conditionLogic.kt
Returns(TRUE) -> x is kotlin/Comparable<*> && x is kotlin/CharSequence || x is kotlin/Number
>
{
[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|((R|<local>/x| is R|kotlin/Comparable<*>|) && (R|<local>/x| is R|kotlin/CharSequence|) || (R|<local>/x| is R|kotlin/Number|))
}
)
}
^test12 (R|<local>/x| is R|kotlin/String|) || (R|<local>/x| is R|kotlin/Int|)
}
@R|kotlin/OptIn|(markerClass = vararg(<getClass>(Q|kotlin/contracts/ExperimentalContracts|))) public final fun test13(x: R|kotlin/Any?|): R|kotlin/Any?|
@@ -119,6 +191,12 @@ FILE: conditionLogic.kt
Returns(TRUE) -> (!)x !is kotlin/Comparable<*> || x !is kotlin/CharSequence && (!x is kotlin/Number)
>
{
[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|((R|<local>/x| !is R|kotlin/Comparable<*>|) || (R|<local>/x| !is R|kotlin/CharSequence|) && (R|<local>/x| is R|kotlin/Number|).R|kotlin/Boolean.not|().R|kotlin/Boolean.not|())
}
)
}
^test13 (R|<local>/x| is R|kotlin/String|) || (R|<local>/x| is R|kotlin/Int|)
}
@@ -13,7 +13,7 @@ fun test1(x: String?): Any? {
@OptIn(ExperimentalContracts::class)
fun test2(x: String?): Any? {
contract {
returnsNotNull() implies (x is String && x != null)
returnsNotNull() implies (x is String)
}
return x
@@ -22,7 +22,7 @@ fun test2(x: String?): Any? {
@OptIn(ExperimentalContracts::class)
fun test3(x: String?): Any? {
contract {
returnsNotNull() implies (x is String? || x is Any?)
returnsNotNull() implies (x !is String)
}
return x
@@ -1,21 +1,34 @@
FILE: eqNotEq.kt
public final fun checkNotNull(x: R|kotlin/Any?|): R|kotlin/Boolean|
@R|kotlin/OptIn|(markerClass = vararg(<getClass>(Q|kotlin/contracts/ExperimentalContracts|))) public final fun checkNotNull(x: R|kotlin/Any?|): R|kotlin/Boolean|
[R|Contract description]
<
Returns(TRUE) -> x != null
Returns(FALSE) -> 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|(Boolean(true)).R|kotlin/contracts/SimpleEffect.implies|(!=(R|<local>/x|, Null(null)))
this@R|special/anonymous|.R|kotlin/contracts/ContractBuilder.returns|(Boolean(false)).R|kotlin/contracts/SimpleEffect.implies|(==(R|<local>/x|, Null(null)))
}
)
}
^checkNotNull !=(R|<local>/x|, Null(null))
}
public final fun trickyRequireNotNull(x: R|kotlin/Any?|): R|kotlin/Unit|
@R|kotlin/OptIn|(markerClass = vararg(<getClass>(Q|kotlin/contracts/ExperimentalContracts|))) public final fun trickyRequireNotNull(x: R|kotlin/Any?|): R|kotlin/Unit|
[R|Contract description]
<
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)).R|kotlin/Boolean.not|())
}
)
}
when () {
==(R|<local>/x|, Null(null)) -> {
throw R|java/lang/IllegalStateException.IllegalStateException|()
@@ -1,5 +1,6 @@
import kotlin.contracts.*
@OptIn(ExperimentalContracts::class)
fun checkNotNull(x: Any?): Boolean {
contract {
returns(true) implies (x != null)
@@ -8,6 +9,7 @@ fun checkNotNull(x: Any?): Boolean {
return x != null
}
@OptIn(ExperimentalContracts::class)
fun trickyRequireNotNull(x: Any?) {
contract {
returns() implies (!(x == null))
@@ -5,7 +5,13 @@ FILE: inapplicable.kt
Returns(FALSE) -> 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|(Boolean(false)).R|kotlin/contracts/SimpleEffect.implies|(!=(R|<local>/x|, Null(null)))
}
)
}
^wrongFalse Boolean(true)
}
@R|kotlin/OptIn|(markerClass = vararg(<getClass>(Q|kotlin/contracts/ExperimentalContracts|))) public final fun wrongTrue(x: R|kotlin/String?|): R|kotlin/Boolean|
@@ -14,7 +20,13 @@ FILE: inapplicable.kt
Returns(TRUE) -> 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|(Boolean(true)).R|kotlin/contracts/SimpleEffect.implies|(!=(R|<local>/x|, Null(null)))
}
)
}
^wrongTrue Boolean(false)
}
@R|kotlin/OptIn|(markerClass = vararg(<getClass>(Q|kotlin/contracts/ExperimentalContracts|))) public final fun nullableConstant(x: R|kotlin/String?|): R|kotlin/Any?|
@@ -23,7 +35,13 @@ FILE: inapplicable.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)))
}
)
}
^nullableConstant Int(1)
}
public final fun string(): R|kotlin/String| {
@@ -35,7 +53,13 @@ FILE: inapplicable.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)))
}
)
}
^nullableReturn R|/string|()
}
@R|kotlin/OptIn|(markerClass = vararg(<getClass>(Q|kotlin/contracts/ExperimentalContracts|))) public final fun returnsNull(x: R|kotlin/String?|): R|kotlin/Any?|
@@ -44,7 +68,13 @@ FILE: inapplicable.kt
Returns(NOT_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.returnsNotNull|().R|kotlin/contracts/SimpleEffect.implies|(!=(R|<local>/x|, Null(null)))
}
)
}
^returnsNull Null(null)
}
@R|kotlin/OptIn|(markerClass = vararg(<getClass>(Q|kotlin/contracts/ExperimentalContracts|))) public final fun wrongReturnType(x: R|kotlin/String?|): R|kotlin/Any?|
@@ -53,6 +83,12 @@ FILE: inapplicable.kt
Returns(TRUE) -> 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|(Boolean(true)).R|kotlin/contracts/SimpleEffect.implies|(!=(R|<local>/x|, Null(null)))
}
)
}
^wrongReturnType String(true)
}
@@ -1,11 +1,17 @@
FILE: namedArguments.kt
public final fun foo(x: R|kotlin/Any|, y: R|kotlin/Any|): R|kotlin/Unit|
@R|kotlin/OptIn|(markerClass = vararg(<getClass>(Q|kotlin/contracts/ExperimentalContracts|))) public final fun foo(x: R|kotlin/Any|, y: R|kotlin/Any|): R|kotlin/Unit|
[R|Contract description]
<
Returns(WILDCARD) -> x is kotlin/Int && y is kotlin/String
>
{
[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| is R|kotlin/Int|) && (R|<local>/y| is R|kotlin/String|))
}
)
}
when () {
(R|<local>/x| !is R|kotlin/Int|) || (R|<local>/y| !is R|kotlin/String|) -> {
throw R|java/lang/IllegalStateException.IllegalStateException|()
@@ -1,5 +1,6 @@
import kotlin.contracts.*
@OptIn(ExperimentalContracts::class)
fun foo(x: Any, y: Any) {
contract {
returns() implies (x is Int && y is String)
@@ -5,7 +5,13 @@ FILE: notNull.kt
Returns(FALSE) -> 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|(Boolean(false)).R|kotlin/contracts/SimpleEffect.implies|(!=(R|<local>/x|, Null(null)))
}
)
}
^test1 ==(R|<local>/x|, Null(null))
}
@R|kotlin/OptIn|(markerClass = vararg(<getClass>(Q|kotlin/contracts/ExperimentalContracts|))) public final fun test2(x: R|kotlin/String?|): R|kotlin/Boolean|
@@ -14,7 +20,13 @@ FILE: notNull.kt
Returns(TRUE) -> 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|(Boolean(true)).R|kotlin/contracts/SimpleEffect.implies|(!=(R|<local>/x|, Null(null)))
}
)
}
^test2 !=(R|<local>/x|, Null(null))
}
@R|kotlin/OptIn|(markerClass = vararg(<getClass>(Q|kotlin/contracts/ExperimentalContracts|))) public final fun test3(x: R|kotlin/String?|): R|kotlin/Any?|
@@ -23,7 +35,13 @@ FILE: notNull.kt
Returns(TRUE) -> 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|(Boolean(true)).R|kotlin/contracts/SimpleEffect.implies|(!=(R|<local>/x|, Null(null)))
}
)
}
when () {
!=(R|<local>/x|, Null(null)) -> {
^test3 Boolean(true)
@@ -38,7 +56,13 @@ FILE: notNull.kt
Returns(TRUE) -> 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|(Boolean(true)).R|kotlin/contracts/SimpleEffect.implies|(!=(R|<local>/x|, Null(null)))
}
)
}
lval y: R|kotlin/String?| = R|<local>/x|
when () {
!=(R|<local>/y|, Null(null)) -> {
@@ -54,6 +78,12 @@ FILE: notNull.kt
Returns(TRUE) -> 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|(Boolean(true)).R|kotlin/contracts/SimpleEffect.implies|(!=(R|<local>/x|, Null(null)))
}
)
}
^test5 R|/test2|(R|<local>/x|)
}
@@ -3,14 +3,20 @@ FILE: propertyAccessors.kt
public abstract fun foo(): R|kotlin/Unit|
}
public final var R|kotlin/Any?|.isNotNull: R|kotlin/Boolean|
@R|kotlin/OptIn|(markerClass = vararg(<getClass>(Q|kotlin/contracts/ExperimentalContracts|))) public final var R|kotlin/Any?|.isNotNull: R|kotlin/Boolean|
public get(): R|kotlin/Boolean|
[R|Contract description]
<
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))
}
public set(value: R|kotlin/Boolean|): R|kotlin/Unit|
@@ -19,7 +25,14 @@ FILE: propertyAccessors.kt
Returns(WILDCARD) -> 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|().R|kotlin/contracts/SimpleEffect.implies|(!=(this@R|/isNotNull|, Null(null)))
R|kotlin/require|(!=(this@R|special/anonymous|, Null(null)))
}
)
}
}
public final fun test_1(a: R|A?|): R|kotlin/Unit| {
when () {
@@ -4,6 +4,7 @@ interface A {
fun foo()
}
@OptIn(ExperimentalContracts::class)
var Any?.isNotNull: Boolean
get() {
contract {
@@ -3,13 +3,19 @@ FILE: receivers.kt
}
public final fun R|A|.foo(): R|kotlin/Unit| {
}
public final fun R|kotlin/Any?|.myRequireNotNull(): R|kotlin/Unit|
@R|kotlin/OptIn|(markerClass = vararg(<getClass>(Q|kotlin/contracts/ExperimentalContracts|))) public final fun R|kotlin/Any?|.myRequireNotNull(): R|kotlin/Unit|
[R|Contract description]
<
Returns(WILDCARD) -> 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|().R|kotlin/contracts/SimpleEffect.implies|(!=(this@R|/myRequireNotNull|, Null(null)))
}
)
}
when () {
==(this@R|/myRequireNotNull|, Null(null)) -> {
throw R|java/lang/IllegalStateException.IllegalStateException|()
@@ -4,6 +4,7 @@ interface A
fun A.foo() {}
@OptIn(ExperimentalContracts::class)
fun Any?.myRequireNotNull() {
contract {
returns() implies (this@myRequireNotNull != null)
@@ -5,7 +5,13 @@ FILE: safeCall.kt
Returns(NOT_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.returnsNotNull|().R|kotlin/contracts/SimpleEffect.implies|(!=(R|<local>/x|, Null(null)))
}
)
}
^test1 R|<local>/x|?.{ $subj$.R|kotlin/String.length| }
}
@R|kotlin/OptIn|(markerClass = vararg(<getClass>(Q|kotlin/contracts/ExperimentalContracts|))) public final fun test2(x: R|kotlin/String?|): R|kotlin/Int?|
@@ -14,6 +20,12 @@ FILE: safeCall.kt
Returns(NOT_NULL) -> x is kotlin/Boolean
>
{
[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.returnsNotNull|().R|kotlin/contracts/SimpleEffect.implies|((R|<local>/x| is R|kotlin/Boolean|))
}
)
}
^test2 R|<local>/x|?.{ $subj$.R|kotlin/String.length| }
}
@@ -5,7 +5,13 @@ FILE: trickyCases.kt
Returns(NOT_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.returnsNotNull|().R|kotlin/contracts/SimpleEffect.implies|(!=(R|<local>/x|, Null(null)))
}
)
}
^test1 R|<local>/x|
}
@R|kotlin/OptIn|(markerClass = vararg(<getClass>(Q|kotlin/contracts/ExperimentalContracts|))) public final fun test2(x: R|kotlin/String?|): R|kotlin/Any?|
@@ -14,7 +20,13 @@ FILE: trickyCases.kt
Returns(TRUE) -> 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|(Boolean(true)).R|kotlin/contracts/SimpleEffect.implies|(!=(R|<local>/x|, Null(null)))
}
)
}
^test2 when () {
!=(R|<local>/x|, Null(null)) -> {
Boolean(true)
@@ -31,7 +43,13 @@ FILE: trickyCases.kt
Returns(NOT_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.returnsNotNull|().R|kotlin/contracts/SimpleEffect.implies|(!=(R|<local>/x|, Null(null)))
}
)
}
^test3 when () {
Boolean(true) -> {
R|<local>/x|
@@ -48,7 +66,13 @@ FILE: trickyCases.kt
Returns(NOT_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.returnsNotNull|().R|kotlin/contracts/SimpleEffect.implies|(!=(R|<local>/x|, Null(null)))
}
)
}
^test4 when () {
!=(R|<local>/x|, Null(null)) -> {
when () {
@@ -1,12 +1,19 @@
FILE: typePredicate.kt
public final fun checkIsString(x: R|kotlin/Any|): R|kotlin/Boolean|
@R|kotlin/OptIn|(markerClass = vararg(<getClass>(Q|kotlin/contracts/ExperimentalContracts|))) 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
>
{
[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|((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| {
@@ -1,5 +1,6 @@
import kotlin.contracts.*
@OptIn(ExperimentalContracts::class)
fun checkIsString(x: Any): Boolean {
contract {
returns(true) implies (x is String)
@@ -12,13 +12,19 @@ FILE: annotationArgumentMapping.kt
}
}
public final fun buildAnnotationArgumentMapping(init: R|FirAnnotationArgumentMappingBuilder.() -> kotlin/Unit|): R|FirAnnotationArgumentMapping|
@R|kotlin/OptIn|(markerClass = vararg(<getClass>(Q|kotlin/contracts/ExperimentalContracts|))) public final fun buildAnnotationArgumentMapping(init: R|FirAnnotationArgumentMappingBuilder.() -> kotlin/Unit|): R|FirAnnotationArgumentMapping|
[R|Contract description]
<
CallsInPlace(init, EXACTLY_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>/init|, Q|kotlin/contracts/InvocationKind|.R|kotlin/contracts/InvocationKind.EXACTLY_ONCE|)
}
)
}
^buildAnnotationArgumentMapping R|/FirAnnotationArgumentMappingBuilder.FirAnnotationArgumentMappingBuilder|().R|kotlin/apply|<R|FirAnnotationArgumentMappingBuilder|>(R|<local>/init|).R|/FirAnnotationArgumentMappingBuilder.build|()
}
public final class FirAnnotationArgumentMapping : R|kotlin/Any| {
@@ -8,6 +8,7 @@ class FirAnnotationArgumentMappingBuilder {
}
}
@OptIn(ExperimentalContracts::class)
fun buildAnnotationArgumentMapping(init: FirAnnotationArgumentMappingBuilder.() -> Unit): FirAnnotationArgumentMapping {
contract {
callsInPlace(init, InvocationKind.EXACTLY_ONCE)
@@ -5193,6 +5193,12 @@ public class FirDiagnosticTestGenerated extends AbstractFirDiagnosticTest {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolveWithStdlib/contracts/fromSource/bad"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
}
@Test
@TestMetadata("noOptIn.kt")
public void testNoOptIn() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolveWithStdlib/contracts/fromSource/bad/noOptIn.kt");
}
@Nested
@TestMetadata("compiler/fir/analysis-tests/testData/resolveWithStdlib/contracts/fromSource/bad/callsInPlace")
@TestDataPath("$PROJECT_ROOT")
@@ -5247,6 +5253,12 @@ public class FirDiagnosticTestGenerated extends AbstractFirDiagnosticTest {
public void testPropertyGetter() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolveWithStdlib/contracts/fromSource/bad/returnsImplies/propertyGetter.kt");
}
@Test
@TestMetadata("redundantConditions.kt")
public void testRedundantConditions() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolveWithStdlib/contracts/fromSource/bad/returnsImplies/redundantConditions.kt");
}
}
}
@@ -5193,6 +5193,12 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolveWithStdlib/contracts/fromSource/bad"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
}
@Test
@TestMetadata("noOptIn.kt")
public void testNoOptIn() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolveWithStdlib/contracts/fromSource/bad/noOptIn.kt");
}
@Nested
@TestMetadata("compiler/fir/analysis-tests/testData/resolveWithStdlib/contracts/fromSource/bad/callsInPlace")
@TestDataPath("$PROJECT_ROOT")
@@ -5247,6 +5253,12 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos
public void testPropertyGetter() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolveWithStdlib/contracts/fromSource/bad/returnsImplies/propertyGetter.kt");
}
@Test
@TestMetadata("redundantConditions.kt")
public void testRedundantConditions() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolveWithStdlib/contracts/fromSource/bad/returnsImplies/redundantConditions.kt");
}
}
}
@@ -34,6 +34,7 @@ abstract class CheckerContext : MutableDiagnosticContext() {
abstract val qualifiedAccessOrAnnotationCalls: List<FirStatement>
abstract val getClassCalls: List<FirGetClassCall>
abstract val annotationContainers: List<FirAnnotationContainer>
abstract val isContractBody: Boolean
// Suppress
abstract val suppressedDiagnostics: Set<String>
@@ -71,6 +72,10 @@ abstract class CheckerContext : MutableDiagnosticContext() {
abstract fun dropAnnotationContainer()
abstract fun enterContractBody(): CheckerContext
abstract fun exitContractBody(): CheckerContext
override fun isDiagnosticSuppressed(diagnostic: KtDiagnostic): Boolean {
val factory = diagnostic.factory
val name = factory.name
@@ -23,6 +23,7 @@ class MutableCheckerContext private constructor(
override val qualifiedAccessOrAnnotationCalls: MutableList<FirStatement>,
override val getClassCalls: MutableList<FirGetClassCall>,
override val annotationContainers: MutableList<FirAnnotationContainer>,
override var isContractBody: Boolean,
sessionHolder: SessionHolder,
returnTypeCalculator: ReturnTypeCalculator,
override val suppressedDiagnostics: PersistentSet<String>,
@@ -36,6 +37,7 @@ class MutableCheckerContext private constructor(
mutableListOf(),
mutableListOf(),
mutableListOf(),
isContractBody = false,
sessionHolder,
returnTypeCalculator,
persistentSetOf(),
@@ -51,6 +53,7 @@ class MutableCheckerContext private constructor(
qualifiedAccessOrAnnotationCalls,
getClassCalls,
annotationContainers,
isContractBody,
sessionHolder,
returnTypeCalculator,
suppressedDiagnostics,
@@ -109,6 +112,7 @@ class MutableCheckerContext private constructor(
qualifiedAccessOrAnnotationCalls,
getClassCalls,
annotationContainers,
isContractBody,
sessionHolder,
returnTypeCalculator,
suppressedDiagnostics.addAll(diagnosticNames),
@@ -117,4 +121,16 @@ class MutableCheckerContext private constructor(
this.allErrorsSuppressed || allErrorsSuppressed
)
}
override fun enterContractBody(): CheckerContext {
check(!isContractBody)
isContractBody = true
return this
}
override fun exitContractBody(): CheckerContext {
check(isContractBody)
isContractBody = false
return this
}
}
@@ -25,6 +25,7 @@ class PersistentCheckerContext private constructor(
override val qualifiedAccessOrAnnotationCalls: PersistentList<FirStatement>,
override val getClassCalls: PersistentList<FirGetClassCall>,
override val annotationContainers: PersistentList<FirAnnotationContainer>,
override val isContractBody: Boolean,
sessionHolder: SessionHolder,
returnTypeCalculator: ReturnTypeCalculator,
override val suppressedDiagnostics: PersistentSet<String>,
@@ -38,6 +39,7 @@ class PersistentCheckerContext private constructor(
persistentListOf(),
persistentListOf(),
persistentListOf(),
isContractBody = false,
sessionHolder,
returnTypeCalculator,
persistentSetOf(),
@@ -53,6 +55,7 @@ class PersistentCheckerContext private constructor(
qualifiedAccessOrAnnotationCalls,
getClassCalls,
annotationContainers,
isContractBody,
sessionHolder,
returnTypeCalculator,
suppressedDiagnostics,
@@ -69,6 +72,7 @@ class PersistentCheckerContext private constructor(
qualifiedAccessOrAnnotationCalls,
getClassCalls,
annotationContainers,
isContractBody,
sessionHolder,
returnTypeCalculator,
suppressedDiagnostics,
@@ -88,6 +92,7 @@ class PersistentCheckerContext private constructor(
this.qualifiedAccessOrAnnotationCalls.add(qualifiedAccessOrAnnotationCall),
getClassCalls,
annotationContainers,
isContractBody,
sessionHolder,
returnTypeCalculator,
suppressedDiagnostics,
@@ -107,6 +112,7 @@ class PersistentCheckerContext private constructor(
qualifiedAccessOrAnnotationCalls,
getClassCalls.add(getClassCall),
annotationContainers,
isContractBody,
sessionHolder,
returnTypeCalculator,
suppressedDiagnostics,
@@ -126,6 +132,7 @@ class PersistentCheckerContext private constructor(
qualifiedAccessOrAnnotationCalls,
getClassCalls,
annotationContainers.add(annotationContainer),
isContractBody,
sessionHolder,
returnTypeCalculator,
suppressedDiagnostics,
@@ -151,6 +158,7 @@ class PersistentCheckerContext private constructor(
qualifiedAccessOrAnnotationCalls,
getClassCalls,
annotationContainers,
isContractBody,
sessionHolder,
returnTypeCalculator,
suppressedDiagnostics.addAll(diagnosticNames),
@@ -159,4 +167,31 @@ class PersistentCheckerContext private constructor(
this.allErrorsSuppressed || allErrorsSuppressed
)
}
private fun toggleContractBody(newValue: Boolean): CheckerContext {
check(isContractBody != newValue)
return PersistentCheckerContext(
implicitReceiverStack,
containingDeclarations,
qualifiedAccessOrAnnotationCalls,
getClassCalls,
annotationContainers,
isContractBody = newValue,
sessionHolder,
returnTypeCalculator,
suppressedDiagnostics,
allInfosSuppressed,
allWarningsSuppressed,
allErrorsSuppressed
)
}
override fun enterContractBody(): CheckerContext {
return toggleContractBody(newValue = true)
}
override fun exitContractBody(): CheckerContext {
return toggleContractBody(newValue = false)
}
}
@@ -26,7 +26,8 @@ object FirContractChecker : FirFunctionChecker() {
}
// Any statements that [ConeEffectExtractor] cannot extract effects will be in `unresolvedEffects`.
for (statement in (declaration.contractDescription as FirResolvedContractDescription).unresolvedEffects) {
for (unresolvedEffect in (declaration.contractDescription as FirResolvedContractDescription).unresolvedEffects) {
val statement = unresolvedEffect.statement
if (statement.source == null || statement.source!!.kind is KtFakeSourceElementKind) continue
// TODO: report on fine-grained locations, e.g., ... implies unresolved => report on unresolved, not the entire statement.
@@ -131,6 +131,7 @@ abstract class FirInlineDeclarationChecker : FirFunctionChecker() {
targetSymbol: FirBasedSymbol<*>?,
context: CheckerContext
) {
if (context.isContractBody) return
val calledFunctionSymbol = targetSymbol as? FirNamedFunctionSymbol ?: return
val argumentMapping = functionCall.resolvedArgumentMapping ?: return
for ((wrappedArgument, valueParameter) in argumentMapping) {
@@ -42,7 +42,7 @@ object FirCastOperatorsChecker : FirTypeOperatorCallChecker() {
reporter.reportOn(expression.source, FirErrors.UNCHECKED_CAST, actualType, targetType, context)
}
} else if (expression.operation == FirOperation.IS) {
if (isCastErased(actualType, targetType, context)) {
if (!context.isContractBody && isCastErased(actualType, targetType, context)) {
reporter.reportOn(conversionTypeRef.source, FirErrors.CANNOT_CHECK_FOR_ERASED, targetType, context)
}
}
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.builder.buildReceiverParameter
import org.jetbrains.kotlin.fir.expressions.*
import org.jetbrains.kotlin.fir.expressions.impl.FirContractCallBlock
import org.jetbrains.kotlin.fir.resolve.defaultType
import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
@@ -166,7 +167,13 @@ abstract class AbstractDiagnosticCollectorVisitor(
override fun visitBlock(block: FirBlock, data: Nothing?) {
withAnnotationContainer(block) {
visitExpression(block, data)
if (block is FirContractCallBlock) {
insideContractBody {
visitExpression(block, data)
}
} else {
visitExpression(block, data)
}
}
}
@@ -352,6 +359,16 @@ abstract class AbstractDiagnosticCollectorVisitor(
}
}
@OptIn(PrivateForInline::class)
private inline fun <R> insideContractBody(block: () -> R): R {
context = context.enterContractBody()
return try {
block()
} finally {
context = context.exitContractBody()
}
}
private inline fun <R> withTypeRefAnnotationContainer(annotationContainer: FirTypeRef, block: () -> R): R {
var containingTypeRef = context.annotationContainers.lastOrNull() as? FirResolvedTypeRef
while (containingTypeRef != null && containingTypeRef.delegatedTypeRef != annotationContainer) {
@@ -25,6 +25,7 @@ import org.jetbrains.kotlin.fir.declarations.utils.isSealed
import org.jetbrains.kotlin.fir.declarations.utils.isSynthetic
import org.jetbrains.kotlin.fir.declarations.utils.visibility
import org.jetbrains.kotlin.fir.expressions.*
import org.jetbrains.kotlin.fir.expressions.impl.FirContractCallBlock
import org.jetbrains.kotlin.fir.expressions.impl.FirElseIfTrueCondition
import org.jetbrains.kotlin.fir.expressions.impl.FirStubStatement
import org.jetbrains.kotlin.fir.expressions.impl.FirUnitExpression
@@ -660,6 +661,7 @@ class Fir2IrVisitor(
if (this is FirTypeAlias) return null
if (this == FirStubStatement) return null
if (this is FirUnitExpression) return convertToIrExpression(this)
if (this is FirContractCallBlock) return null
if (this is FirBlock) return convertToIrExpression(this)
return accept(this@Fir2IrVisitor, null) as IrStatement
}
@@ -1030,7 +1030,7 @@ class DeclarationsConverter(
annotations += modifiers.annotations
typeParameters += constructorTypeParametersFromConstructedClass(classWrapper.classBuilder.typeParameters)
valueParameters += firValueParameters.map { it.firValueParameter }
val (body, _) = convertFunctionBody(block, null)
val (body, _) = convertFunctionBody(block, null, allowLegacyContractDescription = true)
this.body = body
context.firFunctionTargets.removeLast()
}.also {
@@ -1460,9 +1460,8 @@ class DeclarationsConverter(
if (!isGetter) {
valueParameters += firValueParameters
}
val hasContractEffectList = outerContractDescription != null
val bodyWithContractDescription = convertFunctionBody(block, expression, hasContractEffectList)
val allowLegacyContractDescription = outerContractDescription == null
val bodyWithContractDescription = convertFunctionBody(block, expression, allowLegacyContractDescription)
this.body = bodyWithContractDescription.first
val contractDescription = outerContractDescription ?: bodyWithContractDescription.second
contractDescription?.let {
@@ -1720,8 +1719,8 @@ class DeclarationsConverter(
).map { it.firValueParameter }
}
val hasContractEffectList = outerContractDescription != null
val bodyWithContractDescription = convertFunctionBody(block, expression, hasContractEffectList)
val allowLegacyContractDescription = outerContractDescription == null && !isLocal
val bodyWithContractDescription = convertFunctionBody(block, expression, allowLegacyContractDescription)
this.body = bodyWithContractDescription.first
val contractDescription = outerContractDescription ?: bodyWithContractDescription.second
contractDescription?.let {
@@ -1755,16 +1754,13 @@ class DeclarationsConverter(
private fun convertFunctionBody(
blockNode: LighterASTNode?,
expression: LighterASTNode?,
hasContractEffectList: Boolean = false
allowLegacyContractDescription: Boolean
): Pair<FirBlock?, FirContractDescription?> {
return when {
blockNode != null -> {
val block = convertBlock(blockNode)
if (hasContractEffectList) {
block to null
} else {
block.extractContractDescriptionIfPossible()
}
val contractDescription = runIf(allowLegacyContractDescription) { processLegacyContractDescription(block) }
block to contractDescription
}
expression != null -> FirSingleExpressionBlock(
expressionConverter.getAsFirExpression<FirExpression>(expression, "Function has no body (but should)").toReturn()
@@ -363,16 +363,16 @@ open class RawFirBuilder(
}
}
private fun KtDeclarationWithBody.buildFirBody(): Pair<FirBlock?, FirContractDescription?> =
private fun KtDeclarationWithBody.buildFirBody(allowLegacyContractDescription: Boolean): Pair<FirBlock?, FirContractDescription?> =
if (hasBody()) {
buildOrLazyBlock {
if (hasBlockBody()) {
val block = bodyBlockExpression?.accept(this@Visitor, Unit) as? FirBlock
return@buildFirBody if (hasContractEffectList()) {
block to null
} else {
block.extractContractDescriptionIfPossible()
val contractDescription = when {
allowLegacyContractDescription && !hasContractEffectList() -> block?.let(::processLegacyContractDescription)
else -> null
}
return@buildFirBody block to contractDescription
} else {
val result = { bodyExpression }.toFirExpression("Function has no body (but should)")
FirSingleExpressionBlock(result.toReturn(baseSource = result.source))
@@ -469,7 +469,7 @@ open class RawFirBuilder(
}
}
val outerContractDescription = this@toFirPropertyAccessor.obtainContractDescription()
val bodyWithContractDescription = this@toFirPropertyAccessor.buildFirBody()
val bodyWithContractDescription = this@toFirPropertyAccessor.buildFirBody(allowLegacyContractDescription = true)
this.body = bodyWithContractDescription.first
val contractDescription = outerContractDescription ?: bodyWithContractDescription.second
contractDescription?.let {
@@ -1417,6 +1417,7 @@ open class RawFirBuilder(
val labelName: String?
val isAnonymousFunction = function.isAnonymous
val isLocalFunction = function.isLocal
val functionSymbol: FirFunctionSymbol<*>
val functionBuilder = if (isAnonymousFunction) {
FirAnonymousFunctionBuilder().apply {
@@ -1435,7 +1436,7 @@ open class RawFirBuilder(
symbol = FirNamedFunctionSymbol(callableIdForName(function.nameAsSafeName)).also { functionSymbol = it }
dispatchReceiverType = currentDispatchReceiverType()
status = FirDeclarationStatusImpl(
if (function.isLocal) Visibilities.Local else function.visibility,
if (isLocalFunction) Visibilities.Local else function.visibility,
function.modality,
).apply {
isExpect = function.hasExpectModifier() || context.containerIsExpect
@@ -1480,7 +1481,7 @@ open class RawFirBuilder(
listOf()
withCapturedTypeParameters(true, functionSource, actualTypeParameters) {
val outerContractDescription = function.obtainContractDescription()
val bodyWithContractDescription = function.buildFirBody()
val bodyWithContractDescription = function.buildFirBody(!isLocalFunction)
this.body = bodyWithContractDescription.first
val contractDescription = outerContractDescription ?: bodyWithContractDescription.second
contractDescription?.let {
@@ -1653,7 +1654,7 @@ open class RawFirBuilder(
extractValueParametersTo(this, symbol, ValueParameterDeclaration.FUNCTION)
val (body, _) = buildFirBody()
val (body, _) = buildFirBody(allowLegacyContractDescription = true)
this.body = body
this@RawFirBuilder.context.firFunctionTargets.removeLast()
}.also {
@@ -7,7 +7,13 @@ FILE: contractDescription.kt
)
>
{
[StubStatement]
{
contract#(<L> = contract@fun <implicit>.<anonymous>(): <implicit> <inline=Unknown> {
callsInPlace#()
}
)
}
test_1#()
}
public? final? fun test_2(): R|kotlin/Unit|
@@ -19,7 +25,14 @@ FILE: contractDescription.kt
)
>
{
[StubStatement]
{
kotlin#.contracts#.contract#(<L> = contract@fun <implicit>.<anonymous>(): <implicit> <inline=Unknown> {
callsInPlace#()
callsInPlace#()
}
)
}
test_2#()
}
public? final? var test_3: Int = IntegerLiteral(1)
@@ -31,7 +44,13 @@ FILE: contractDescription.kt
)
>
{
[StubStatement]
{
contract#(<L> = contract@fun <implicit>.<anonymous>(): <implicit> <inline=Unknown> {
callsInPlace#()
}
)
}
^ IntegerLiteral(1)
}
public? set(value: Int): R|kotlin/Unit|
@@ -43,14 +62,24 @@ FILE: contractDescription.kt
)
>
{
[StubStatement]
{
kotlin#.contracts#.contract#(<L> = contract@fun <implicit>.<anonymous>(): <implicit> <inline=Unknown> {
callsInPlace#()
callsInPlace#()
}
)
}
}
public? final? fun test_4(): R|kotlin/Unit|
[Contract description] <
contract#()
>
{
[StubStatement]
{
contract#()
}
test_4#()
}
public? final? fun test_5(): R|kotlin/Unit| {
@@ -13,12 +13,14 @@ import com.intellij.util.PathUtil
import org.jetbrains.kotlin.KtNodeTypes
import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.FirFunctionTypeParameter
import org.jetbrains.kotlin.fir.contracts.FirContractDescription
import org.jetbrains.kotlin.fir.contracts.impl.FirEmptyContractDescription
import org.jetbrains.kotlin.fir.declarations.FirFile
import org.jetbrains.kotlin.fir.declarations.FirTypeParameter
import org.jetbrains.kotlin.fir.declarations.FirValueParameter
import org.jetbrains.kotlin.fir.declarations.impl.FirResolvedDeclarationStatusImpl
import org.jetbrains.kotlin.fir.expressions.*
import org.jetbrains.kotlin.fir.expressions.impl.FirContractCallBlock
import org.jetbrains.kotlin.fir.expressions.impl.FirNoReceiverExpression
import org.jetbrains.kotlin.fir.expressions.impl.FirStubStatement
import org.jetbrains.kotlin.fir.references.impl.FirStubReference
@@ -182,12 +184,13 @@ abstract class AbstractRawFirBuilderTestCase : KtParsingTestCase(
}
}
private fun throwTwiceVisitingError(element: FirElement, @Suppress("UNUSED_PARAMETER") parent: FirElement?) {
private fun throwTwiceVisitingError(element: FirElement, parent: FirElement?) {
if (element is FirTypeRef || element is FirNoReceiverExpression || element is FirTypeParameter ||
element is FirTypeProjection || element is FirValueParameter || element is FirAnnotation || element is FirFunctionTypeParameter ||
element is FirEmptyContractDescription ||
element is FirStubReference || element.isExtensionFunctionAnnotation || element is FirEmptyArgumentList ||
element is FirStubStatement || element === FirResolvedDeclarationStatusImpl.DEFAULT_STATUS_FOR_STATUSLESS_DECLARATIONS
element is FirStubStatement || element === FirResolvedDeclarationStatusImpl.DEFAULT_STATUS_FOR_STATUSLESS_DECLARATIONS ||
((parent is FirContractCallBlock || parent is FirContractDescription) && element is FirFunctionCall)
) {
return
}
@@ -26,8 +26,8 @@ import org.jetbrains.kotlin.fir.diagnostics.ConeDiagnostic
import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind
import org.jetbrains.kotlin.fir.expressions.*
import org.jetbrains.kotlin.fir.expressions.builder.*
import org.jetbrains.kotlin.fir.expressions.impl.FirContractCallBlock
import org.jetbrains.kotlin.fir.expressions.impl.FirSingleExpressionBlock
import org.jetbrains.kotlin.fir.expressions.impl.FirStubStatement
import org.jetbrains.kotlin.fir.references.FirNamedReference
import org.jetbrains.kotlin.fir.references.builder.buildDelegateFieldReference
import org.jetbrains.kotlin.fir.references.builder.buildImplicitThisReference
@@ -496,14 +496,16 @@ fun <T> FirPropertyBuilder.generateAccessorsByDelegate(
}
}
fun FirBlock?.extractContractDescriptionIfPossible(): Pair<FirBlock?, FirContractDescription?> {
if (this == null) return null to null
if (!isContractPresentFirCheck()) return this to null
val contractCall = replaceFirstStatement(FirStubStatement) as FirFunctionCall
return this to buildLegacyRawContractDescription {
source = contractCall.source
this.contractCall = contractCall
fun processLegacyContractDescription(block: FirBlock): FirContractDescription? {
if (block.isContractPresentFirCheck()) {
val contractCall = block.replaceFirstStatement<FirFunctionCall> { FirContractCallBlock(it) }
return buildLegacyRawContractDescription {
source = contractCall.source
this.contractCall = contractCall
}
}
return null
}
fun FirBlock.isContractPresentFirCheck(): Boolean {
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.fir.contracts.FirRawContractDescription
import org.jetbrains.kotlin.fir.contracts.builder.buildLegacyRawContractDescription
import org.jetbrains.kotlin.fir.contracts.builder.buildResolvedContractDescription
import org.jetbrains.kotlin.fir.contracts.description.ConeEffectDeclaration
import org.jetbrains.kotlin.fir.contracts.description.ConeUnresolvedEffect
import org.jetbrains.kotlin.fir.contracts.impl.FirEmptyContractDescription
import org.jetbrains.kotlin.fir.contracts.toFirEffectDeclaration
import org.jetbrains.kotlin.fir.declarations.*
@@ -20,6 +21,7 @@ import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticProperty
import org.jetbrains.kotlin.fir.errorTypeFromPrototype
import org.jetbrains.kotlin.fir.expressions.*
import org.jetbrains.kotlin.fir.expressions.builder.*
import org.jetbrains.kotlin.fir.expressions.impl.FirContractCallBlock
import org.jetbrains.kotlin.fir.moduleData
import org.jetbrains.kotlin.fir.references.builder.buildSimpleNamedReference
import org.jetbrains.kotlin.fir.resolve.ResolutionMode
@@ -128,35 +130,53 @@ abstract class FirAbstractContractResolveTransformerDispatcher(
}
}
private fun <T : FirContractDescriptionOwner> transformContractDescriptionOwner(
owner: T
): T {
private fun <T : FirContractDescriptionOwner> transformContractDescriptionOwner(owner: T): T {
dataFlowAnalyzer.enterContractDescription()
return when (val contractDescription = owner.contractDescription) {
is FirLegacyRawContractDescription -> transformLegacyRawContractDescriptionOwner(owner, contractDescription)
is FirRawContractDescription -> transformRawContractDescriptionOwner(owner, contractDescription)
else -> throw IllegalArgumentException("$owner has a contract description of an unknown type")
is FirLegacyRawContractDescription ->
transformLegacyRawContractDescriptionOwner(owner, contractDescription, hasBodyContract = true)
is FirRawContractDescription ->
transformRawContractDescriptionOwner(owner, contractDescription)
else ->
throw IllegalArgumentException("$owner has a contract description of an unknown type")
}
}
private fun <T : FirContractDescriptionOwner> transformLegacyRawContractDescriptionOwner(
owner: T,
contractDescription: FirLegacyRawContractDescription
contractDescription: FirLegacyRawContractDescription,
hasBodyContract: Boolean
): T {
val valueParameters = owner.valueParameters
for (valueParameter in valueParameters) {
context.storeVariable(valueParameter, session)
}
val contractCall = try {
contractMode = false
contractDescription.contractCall.transformSingle(transformer, ResolutionMode.ContextIndependent)
} finally {
contractMode = true
val resolvedContractCall = withContractModeDisabled {
contractDescription.contractCall
.transformSingle(transformer, ResolutionMode.ContextIndependent)
.apply { replaceTypeRef(session.builtinTypes.unitType) }
}
val resolvedId = contractCall.toResolvedCallableSymbol()?.callableId ?: return transformOwnerWithUnresolvedContract(owner)
if (resolvedId != FirContractsDslNames.CONTRACT) return transformOwnerWithUnresolvedContract(owner)
if (contractCall.arguments.size != 1) return transformOwnerOfErrorContract(owner)
val argument = contractCall.argument as? FirLambdaArgumentExpression ?: return transformOwnerOfErrorContract(owner)
if (resolvedContractCall.toResolvedCallableSymbol()?.callableId != FirContractsDslNames.CONTRACT) {
if (hasBodyContract) {
owner.body.replaceFirstStatement<FirContractCallBlock> { resolvedContractCall }
}
owner.replaceContractDescription(FirEmptyContractDescription)
dataFlowAnalyzer.exitContractDescription()
return owner
}
if (hasBodyContract) {
// Until the contract description is replaced with a resolved one, a call rests both in the description
// and in the callable body (scoped inside a marker block). Here we patch the second call occurrence.
owner.body.replaceFirstStatement<FirContractCallBlock> { FirContractCallBlock(resolvedContractCall) }
}
val argument = resolvedContractCall.arguments.singleOrNull() as? FirLambdaArgumentExpression
?: return transformOwnerOfErrorContract(owner)
val lambdaBody = (argument.expression as FirAnonymousFunctionExpression).anonymousFunction.body
?: return transformOwnerOfErrorContract(owner)
@@ -165,18 +185,27 @@ abstract class FirAbstractContractResolveTransformerDispatcher(
for (statement in lambdaBody.statements) {
val effect = statement.accept(effectExtractor, null) as? ConeEffectDeclaration
if (effect == null) {
unresolvedEffects += statement
unresolvedEffects += ConeUnresolvedEffect(statement)
} else {
effects += effect.toFirEffectDeclaration(statement.source)
}
}
this.source = owner.contractDescription.source
this.source = contractDescription.source
}
owner.replaceContractDescription(resolvedContractDescription)
dataFlowAnalyzer.exitContractDescription()
return owner
}
private inline fun <T> withContractModeDisabled(block: () -> T): T {
try {
contractMode = false
return block()
} finally {
contractMode = true
}
}
private fun <T : FirContractDescriptionOwner> transformRawContractDescriptionOwner(
owner: T,
contractDescription: FirRawContractDescription
@@ -220,25 +249,7 @@ abstract class FirAbstractContractResolveTransformerDispatcher(
owner.replaceContractDescription(legacyRawContractDescription)
return transformLegacyRawContractDescriptionOwner(owner, legacyRawContractDescription)
}
private fun <T : FirContractDescriptionOwner> transformOwnerWithUnresolvedContract(owner: T): T {
return when (val contractDescription = owner.contractDescription) {
is FirLegacyRawContractDescription -> { // old syntax contract description
val functionCall = contractDescription.contractCall
owner.replaceContractDescription(FirEmptyContractDescription)
owner.body.replaceFirstStatement(functionCall)
dataFlowAnalyzer.exitContractDescription()
owner
}
is FirRawContractDescription -> { // new syntax contract description
owner.replaceContractDescription(FirEmptyContractDescription)
dataFlowAnalyzer.exitContractDescription()
owner
}
else -> owner // TODO: change
}
return transformLegacyRawContractDescriptionOwner(owner, legacyRawContractDescription, hasBodyContract = false)
}
open fun transformDeclarationContent(firClass: FirClass, data: ResolutionMode) {
@@ -7,7 +7,7 @@ package org.jetbrains.kotlin.fir.contracts
import org.jetbrains.kotlin.KtSourceElement
import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.expressions.FirStatement
import org.jetbrains.kotlin.fir.contracts.description.ConeUnresolvedEffect
import org.jetbrains.kotlin.fir.visitors.*
/*
@@ -18,7 +18,7 @@ import org.jetbrains.kotlin.fir.visitors.*
abstract class FirResolvedContractDescription : FirContractDescription() {
abstract override val source: KtSourceElement?
abstract val effects: List<FirEffectDeclaration>
abstract val unresolvedEffects: List<FirStatement>
abstract val unresolvedEffects: List<ConeUnresolvedEffect>
override fun <R, D> accept(visitor: FirVisitor<R, D>, data: D): R = visitor.visitResolvedContractDescription(this, data)
@@ -12,8 +12,8 @@ import org.jetbrains.kotlin.KtSourceElement
import org.jetbrains.kotlin.fir.builder.FirBuilderDsl
import org.jetbrains.kotlin.fir.contracts.FirEffectDeclaration
import org.jetbrains.kotlin.fir.contracts.FirResolvedContractDescription
import org.jetbrains.kotlin.fir.contracts.description.ConeUnresolvedEffect
import org.jetbrains.kotlin.fir.contracts.impl.FirResolvedContractDescriptionImpl
import org.jetbrains.kotlin.fir.expressions.FirStatement
import org.jetbrains.kotlin.fir.visitors.*
/*
@@ -25,7 +25,7 @@ import org.jetbrains.kotlin.fir.visitors.*
class FirResolvedContractDescriptionBuilder {
var source: KtSourceElement? = null
val effects: MutableList<FirEffectDeclaration> = mutableListOf()
val unresolvedEffects: MutableList<FirStatement> = mutableListOf()
val unresolvedEffects: MutableList<ConeUnresolvedEffect> = mutableListOf()
fun build(): FirResolvedContractDescription {
return FirResolvedContractDescriptionImpl(
@@ -10,7 +10,7 @@ package org.jetbrains.kotlin.fir.contracts.impl
import org.jetbrains.kotlin.KtSourceElement
import org.jetbrains.kotlin.fir.contracts.FirEffectDeclaration
import org.jetbrains.kotlin.fir.contracts.FirResolvedContractDescription
import org.jetbrains.kotlin.fir.expressions.FirStatement
import org.jetbrains.kotlin.fir.contracts.description.ConeUnresolvedEffect
import org.jetbrains.kotlin.fir.visitors.*
/*
@@ -21,16 +21,14 @@ import org.jetbrains.kotlin.fir.visitors.*
internal class FirResolvedContractDescriptionImpl(
override val source: KtSourceElement?,
override val effects: MutableList<FirEffectDeclaration>,
override val unresolvedEffects: MutableList<FirStatement>,
override val unresolvedEffects: MutableList<ConeUnresolvedEffect>,
) : FirResolvedContractDescription() {
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {
effects.forEach { it.accept(visitor, data) }
unresolvedEffects.forEach { it.accept(visitor, data) }
}
override fun <D> transformChildren(transformer: FirTransformer<D>, data: D): FirResolvedContractDescriptionImpl {
effects.transformInplace(transformer, data)
unresolvedEffects.transformInplace(transformer, data)
return this
}
}
@@ -0,0 +1,10 @@
/*
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.fir.contracts.description
import org.jetbrains.kotlin.fir.expressions.FirStatement
class ConeUnresolvedEffect(val statement: FirStatement)
@@ -104,13 +104,14 @@ fun <D> FirBlock.transformStatementsIndexed(transformer: FirTransformer<D>, data
return this
}
fun FirBlock.replaceFirstStatement(statement: FirStatement): FirStatement {
fun <T : FirStatement> FirBlock.replaceFirstStatement(factory: (T) -> FirStatement): T {
require(this is FirBlockImpl) {
"replaceFirstStatement should not be called for ${this::class.simpleName}"
}
val existed = statements[0]
statements[0] = statement
return existed
@Suppress("UNCHECKED_CAST")
val existing = statements[0] as T
statements[0] = factory(existing)
return existing
}
fun FirExpression.unwrapArgument(): FirExpression = (this as? FirWrappedArgumentExpression)?.expression ?: this
@@ -0,0 +1,67 @@
/*
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.fir.expressions.impl
import org.jetbrains.kotlin.KtFakeSourceElementKind
import org.jetbrains.kotlin.KtSourceElement
import org.jetbrains.kotlin.fakeElement
import org.jetbrains.kotlin.fir.MutableOrEmptyList
import org.jetbrains.kotlin.fir.builder.toMutableOrEmpty
import org.jetbrains.kotlin.fir.expressions.FirAnnotation
import org.jetbrains.kotlin.fir.expressions.FirBlock
import org.jetbrains.kotlin.fir.expressions.FirFunctionCall
import org.jetbrains.kotlin.fir.expressions.FirStatement
import org.jetbrains.kotlin.fir.types.FirTypeRef
import org.jetbrains.kotlin.fir.types.impl.FirImplicitTypeRefImpl
import org.jetbrains.kotlin.fir.visitors.FirTransformer
import org.jetbrains.kotlin.fir.visitors.FirVisitor
import org.jetbrains.kotlin.fir.visitors.transformInplace
import org.jetbrains.kotlin.fir.visitors.transformSingle
class FirContractCallBlock(var call: FirFunctionCall) : FirBlock() {
override val source: KtSourceElement?
get() = call.source?.fakeElement(KtFakeSourceElementKind.ContractBlock)
override val statements: List<FirStatement>
get() = listOf(call)
override var annotations: MutableOrEmptyList<FirAnnotation> = MutableOrEmptyList.empty()
override var typeRef: FirTypeRef = FirImplicitTypeRefImpl(null)
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {
call.accept(visitor, data)
typeRef.accept(visitor, data)
}
override fun <D> transformChildren(transformer: FirTransformer<D>, data: D): FirContractCallBlock {
transformStatements(transformer, data)
transformOtherChildren(transformer, data)
return this
}
override fun replaceTypeRef(newTypeRef: FirTypeRef) {
typeRef = newTypeRef
}
override fun <D> transformStatements(transformer: FirTransformer<D>, data: D): FirBlock {
call = call.transformSingle(transformer, data)
return this
}
override fun <D> transformOtherChildren(transformer: FirTransformer<D>, data: D): FirBlock {
typeRef = typeRef.transformSingle(transformer, data)
return this
}
override fun replaceAnnotations(newAnnotations: List<FirAnnotation>) {
annotations = newAnnotations.toMutableOrEmpty()
}
override fun <D> transformAnnotations(transformer: FirTransformer<D>, data: D): FirBlock {
annotations.transformInplace(transformer, data)
return this
}
}
@@ -726,7 +726,7 @@ object NodeConfigurator : AbstractFieldConfigurator<FirTreeBuilder>(FirTreeBuild
resolvedContractDescription.configure {
+fieldList("effects", effectDeclaration)
+fieldList("unresolvedEffects", statement)
+fieldList("unresolvedEffects", coneUnresolvedEffect)
}
legacyRawContractDescription.configure {
@@ -80,6 +80,7 @@ val coneEffectDeclarationType = type("fir.contracts.description", "ConeEffectDec
val emptyContractDescriptionType = generatedType("contracts.impl", "FirEmptyContractDescription")
val coneDiagnosticType = generatedType("diagnostics", "ConeDiagnostic")
val coneStubDiagnosticType = generatedType("diagnostics", "ConeStubDiagnostic")
val coneUnresolvedEffect = type("fir.contracts.description", "ConeUnresolvedEffect")
val dslBuilderAnnotationType = generatedType("builder", "FirBuilderDsl")
val firImplementationDetailType = generatedType("FirImplementationDetail")
@@ -113,6 +113,9 @@ sealed class KtFakeSourceElementKind : KtSourceElementKind() {
// with a fake sources for the block which refers to the wrapped expression
object SingleExpressionBlock : KtFakeSourceElementKind()
// Contract statements are wrapped in a special block to be reused between a contract FIR and a function body.
object ContractBlock : KtFakeSourceElementKind()
// x++ -> x = x.inc()
// x = x++ -> x = { val <unary> = x; x = <unary>.inc(); <unary> }
object DesugaredIncrementOrDecrement : KtFakeSourceElementKind()
@@ -156,29 +156,29 @@ fun <T> T?.case_22_3(): Boolean? {
// TESTCASE NUMBER: 23
fun <T : Number?> T.case_23_1(): Boolean {
contract { returns(false) implies (this@case_23_1 !is Int || this@case_23_1 == null) }
contract { returns(false) implies (this@case_23_1 !is Int || <!SENSELESS_COMPARISON!>this@case_23_1 == null<!>) }
return !(this@case_23_1 !is Int || <!SENSELESS_COMPARISON!>this@case_23_1 == null<!>)
}
fun <T : Number?> T.case_23_2(): Boolean? {
contract { returnsNotNull() implies (this@case_23_2 !is Int || this@case_23_2 == null) }
contract { returnsNotNull() implies (this@case_23_2 !is Int || <!SENSELESS_COMPARISON!>this@case_23_2 == null<!>) }
return if (this@case_23_2 !is Int || <!SENSELESS_COMPARISON!>this@case_23_2 == null<!>) true else null
}
fun <T : Number?> T.case_23_3(): Boolean? {
contract { returns(null) implies (this@case_23_3 !is Int || this@case_23_3 == null) }
contract { returns(null) implies (this@case_23_3 !is Int || <!SENSELESS_COMPARISON!>this@case_23_3 == null<!>) }
return if (this@case_23_3 !is Int || <!SENSELESS_COMPARISON!>this@case_23_3 == null<!>) null else true
}
// TESTCASE NUMBER: 24
inline fun <reified T : Any?> T?.case_24_1(): Boolean {
contract { returns(false) implies (this@case_24_1 !is Number || this@case_24_1 !is Int || this@case_24_1 == null) }
contract { returns(false) implies (this@case_24_1 !is Number || this@case_24_1 !is Int || <!SENSELESS_COMPARISON!>this@case_24_1 == null<!>) }
return !(this@case_24_1 !is Number || this@case_24_1 !is Int || <!SENSELESS_COMPARISON!>this@case_24_1 == null<!>)
}
inline fun <reified T : Any?> T?.case_24_2(): Boolean? {
contract { returnsNotNull() implies (this@case_24_2 !is Number || this@case_24_2 !is Int || this@case_24_2 == null) }
contract { returnsNotNull() implies (this@case_24_2 !is Number || this@case_24_2 !is Int || <!SENSELESS_COMPARISON!>this@case_24_2 == null<!>) }
return if (this@case_24_2 !is Number || this@case_24_2 !is Int || <!SENSELESS_COMPARISON!>this@case_24_2 == null<!>) true else null
}
inline fun <reified T : Any?> T?.case_24_3(): Boolean? {
contract { returns(null) implies (this@case_24_3 !is Number || this@case_24_3 !is Int || this@case_24_3 == null) }
contract { returns(null) implies (this@case_24_3 !is Number || this@case_24_3 !is Int || <!SENSELESS_COMPARISON!>this@case_24_3 == null<!>) }
return if (this@case_24_3 !is Number || this@case_24_3 !is Int || <!SENSELESS_COMPARISON!>this@case_24_3 == null<!>) null else true
}
@@ -14,13 +14,13 @@ fun <T> T?.case_1() {
// TESTCASE NUMBER: 2
fun <T : Number?> T.case_2() {
contract { returns() implies (this@case_2 !is Int || this@case_2 == null) }
contract { returns() implies (this@case_2 !is Int || <!SENSELESS_COMPARISON!>this@case_2 == null<!>) }
if (!(this@case_2 !is Int || <!SENSELESS_COMPARISON!>this@case_2 == null<!>)) throw Exception()
}
// TESTCASE NUMBER: 3
inline fun <reified T : Any?> T?.case_3() {
contract { returns() implies (this@case_3 !is Number || this@case_3 !is Int || this@case_3 == null) }
contract { returns() implies (this@case_3 !is Number || this@case_3 !is Int || <!SENSELESS_COMPARISON!>this@case_3 == null<!>) }
if (!(this@case_3 !is Number || this@case_3 !is Int || <!SENSELESS_COMPARISON!>this@case_3 == null<!>)) throw Exception()
}
@@ -44,37 +44,37 @@ fun <T> T?.case_4_4(): Boolean? {
// TESTCASE NUMBER: 5
fun <T : Number?> T.case_5_1(): Boolean {
contract { returns(true) implies (this@case_5_1 !is Int || this@case_5_1 == null) }
contract { returns(true) implies (this@case_5_1 !is Int || <!SENSELESS_COMPARISON!>this@case_5_1 == null<!>) }
return this@case_5_1 !is Int || <!SENSELESS_COMPARISON!>this@case_5_1 == null<!>
}
fun <T : Number?> T.case_5_2(): Boolean {
contract { returns(false) implies (this@case_5_2 !is Int || this@case_5_2 == null) }
contract { returns(false) implies (this@case_5_2 !is Int || <!SENSELESS_COMPARISON!>this@case_5_2 == null<!>) }
return !(this@case_5_2 !is Int || <!SENSELESS_COMPARISON!>this@case_5_2 == null<!>)
}
fun <T : Number?> T.case_5_3(): Boolean? {
contract { returnsNotNull() implies (this@case_5_3 !is Int || this@case_5_3 == null) }
contract { returnsNotNull() implies (this@case_5_3 !is Int || <!SENSELESS_COMPARISON!>this@case_5_3 == null<!>) }
return if (this@case_5_3 !is Int || <!SENSELESS_COMPARISON!>this@case_5_3 == null<!>) true else null
}
fun <T : Number?> T.case_5_4(): Boolean? {
contract { returns(null) implies (this@case_5_4 !is Int || this@case_5_4 == null) }
contract { returns(null) implies (this@case_5_4 !is Int || <!SENSELESS_COMPARISON!>this@case_5_4 == null<!>) }
return if (this@case_5_4 !is Int || <!SENSELESS_COMPARISON!>this@case_5_4 == null<!>) null else true
}
// TESTCASE NUMBER: 6
inline fun <reified T : Any?> T?.case_6_1(): Boolean {
contract { returns(true) implies (this@case_6_1 !is Number || this@case_6_1 !is Int || this@case_6_1 == null) }
contract { returns(true) implies (this@case_6_1 !is Number || this@case_6_1 !is Int || <!SENSELESS_COMPARISON!>this@case_6_1 == null<!>) }
return this@case_6_1 !is Number || this@case_6_1 !is Int || <!SENSELESS_COMPARISON!>this@case_6_1 == null<!>
}
inline fun <reified T : Any?> T?.case_6_2(): Boolean {
contract { returns(false) implies (this@case_6_2 !is Number || this@case_6_2 !is Int || this@case_6_2 == null) }
contract { returns(false) implies (this@case_6_2 !is Number || this@case_6_2 !is Int || <!SENSELESS_COMPARISON!>this@case_6_2 == null<!>) }
return !(this@case_6_2 !is Number || this@case_6_2 !is Int || <!SENSELESS_COMPARISON!>this@case_6_2 == null<!>)
}
inline fun <reified T : Any?> T?.case_6_3(): Boolean? {
contract { returnsNotNull() implies (this@case_6_3 is Number && this@case_6_3 is Int && this@case_6_3 != null) }
contract { returnsNotNull() implies (this@case_6_3 is Number && this@case_6_3 is Int && <!SENSELESS_COMPARISON!>this@case_6_3 != null<!>) }
return if (this@case_6_3 is Number && this@case_6_3 is Int && <!SENSELESS_COMPARISON!>this@case_6_3 != null<!>) true else null
}
inline fun <reified T : Any?> T?.case_6_4(): Boolean? {
contract { returns(null) implies (this@case_6_4 is Number && this@case_6_4 is Int && this@case_6_4 != null) }
contract { returns(null) implies (this@case_6_4 is Number && this@case_6_4 is Int && <!SENSELESS_COMPARISON!>this@case_6_4 != null<!>) }
return if (this@case_6_4 is Number && this@case_6_4 is Int && <!SENSELESS_COMPARISON!>this@case_6_4 != null<!>) null else true
}
@@ -14,13 +14,13 @@ fun <T> T?.case_1(value_1: Int?) {
// TESTCASE NUMBER: 2
fun <T : Number?> T.case_2(value_2: Any?) {
contract { returns() implies (this@case_2 !is Int || this@case_2 == null || value_2 !is Number || value_2 == null) }
contract { returns() implies (this@case_2 !is Int || <!SENSELESS_COMPARISON!>this@case_2 == null<!> || value_2 !is Number || <!SENSELESS_COMPARISON!>value_2 == null<!>) }
if (!(this@case_2 !is Int || <!SENSELESS_COMPARISON!>this@case_2 == null<!> || value_2 !is Number || <!SENSELESS_COMPARISON!>value_2 == null<!>)) throw Exception()
}
// TESTCASE NUMBER: 3
fun <T : Any?> T?.case_3(value_2: Any?) {
contract { returns() implies (this@case_3 !is Number || this@case_3 !is Int || this@case_3 == null || value_2 == null) }
contract { returns() implies (this@case_3 !is Number || this@case_3 !is Int || <!SENSELESS_COMPARISON!>this@case_3 == null<!> || value_2 == null) }
if (!(this@case_3 !is Number || this@case_3 !is Int || <!SENSELESS_COMPARISON!>this@case_3 == null<!> || value_2 == null)) throw Exception()
}
@@ -50,37 +50,37 @@ fun <T> T?.case_5_4(value_1: Int?): Boolean? {
// TESTCASE NUMBER: 6
fun <T : Number?> T.case_6_1(value_2: Any?): Boolean {
contract { returns(true) implies (this@case_6_1 !is Int || this@case_6_1 == null || value_2 !is Number || value_2 == null) }
contract { returns(true) implies (this@case_6_1 !is Int || <!SENSELESS_COMPARISON!>this@case_6_1 == null<!> || value_2 !is Number || <!SENSELESS_COMPARISON!>value_2 == null<!>) }
return this@case_6_1 !is Int || <!SENSELESS_COMPARISON!>this@case_6_1 == null<!> || value_2 !is Number || <!SENSELESS_COMPARISON!>value_2 == null<!>
}
fun <T : Number?> T.case_6_2(value_2: Any?): Boolean {
contract { returns(false) implies (this@case_6_2 !is Int || this@case_6_2 == null || value_2 !is Number || value_2 == null) }
contract { returns(false) implies (this@case_6_2 !is Int || <!SENSELESS_COMPARISON!>this@case_6_2 == null<!> || value_2 !is Number || <!SENSELESS_COMPARISON!>value_2 == null<!>) }
return !(this@case_6_2 !is Int || <!SENSELESS_COMPARISON!>this@case_6_2 == null<!> || value_2 !is Number || <!SENSELESS_COMPARISON!>value_2 == null<!>)
}
fun <T : Number?> T.case_6_3(value_2: Any?): Boolean? {
contract { returnsNotNull() implies (this@case_6_3 !is Int || this@case_6_3 == null || value_2 !is Number || value_2 == null) }
contract { returnsNotNull() implies (this@case_6_3 !is Int || <!SENSELESS_COMPARISON!>this@case_6_3 == null<!> || value_2 !is Number || <!SENSELESS_COMPARISON!>value_2 == null<!>) }
return if (this@case_6_3 !is Int || <!SENSELESS_COMPARISON!>this@case_6_3 == null<!> || value_2 !is Number || <!SENSELESS_COMPARISON!>value_2 == null<!>) true else null
}
fun <T : Number?> T.case_6_4(value_2: Any?): Boolean? {
contract { returns(null) implies (this@case_6_4 !is Int || this@case_6_4 == null || value_2 !is Number || value_2 == null) }
contract { returns(null) implies (this@case_6_4 !is Int || <!SENSELESS_COMPARISON!>this@case_6_4 == null<!> || value_2 !is Number || <!SENSELESS_COMPARISON!>value_2 == null<!>) }
return if (this@case_6_4 !is Int || <!SENSELESS_COMPARISON!>this@case_6_4 == null<!> || value_2 !is Number || <!SENSELESS_COMPARISON!>value_2 == null<!>) null else true
}
// TESTCASE NUMBER: 7
fun <T : Any?> T?.case_7_1(value_2: Any?): Boolean {
contract { returns(true) implies (this@case_7_1 !is Number || this@case_7_1 !is Int || this@case_7_1 == null || value_2 == null) }
contract { returns(true) implies (this@case_7_1 !is Number || this@case_7_1 !is Int || <!SENSELESS_COMPARISON!>this@case_7_1 == null<!> || value_2 == null) }
return this@case_7_1 !is Number || this@case_7_1 !is Int || <!SENSELESS_COMPARISON!>this@case_7_1 == null<!> || value_2 == null
}
fun <T : Any?> T?.case_7_2(value_2: Any?): Boolean {
contract { returns(false) implies (this@case_7_2 !is Number || this@case_7_2 !is Int || this@case_7_2 == null || value_2 == null) }
contract { returns(false) implies (this@case_7_2 !is Number || this@case_7_2 !is Int || <!SENSELESS_COMPARISON!>this@case_7_2 == null<!> || value_2 == null) }
return !(this@case_7_2 !is Number || this@case_7_2 !is Int || <!SENSELESS_COMPARISON!>this@case_7_2 == null<!> || value_2 == null)
}
fun <T : Any?> T?.case_7_3(value_2: Any?): Boolean? {
contract { returnsNotNull() implies (this@case_7_3 !is Number || this@case_7_3 !is Int || this@case_7_3 == null || value_2 == null) }
contract { returnsNotNull() implies (this@case_7_3 !is Number || this@case_7_3 !is Int || <!SENSELESS_COMPARISON!>this@case_7_3 == null<!> || value_2 == null) }
return if (this@case_7_3 !is Number || this@case_7_3 !is Int || <!SENSELESS_COMPARISON!>this@case_7_3 == null<!> || value_2 == null) true else null
}
fun <T : Any?> T?.case_7_4(value_2: Any?): Boolean? {
contract { returns(null) implies (this@case_7_4 !is Number || this@case_7_4 !is Int || this@case_7_4 == null || value_2 == null) }
contract { returns(null) implies (this@case_7_4 !is Number || this@case_7_4 !is Int || <!SENSELESS_COMPARISON!>this@case_7_4 == null<!> || value_2 == null) }
return if (this@case_7_4 !is Number || this@case_7_4 !is Int || <!SENSELESS_COMPARISON!>this@case_7_4 == null<!> || value_2 == null) null else true
}
@@ -14,13 +14,13 @@ fun <T> T?.case_1() {
// TESTCASE NUMBER: 2
fun <T : Number?> T.case_2() {
contract { returns() implies (this@case_2 is Int && this@case_2 != null) }
contract { returns() implies (this@case_2 is Int && <!SENSELESS_COMPARISON!>this@case_2 != null<!>) }
if (!(this@case_2 is Int && <!SENSELESS_COMPARISON!>this@case_2 != null<!>)) throw Exception()
}
// TESTCASE NUMBER: 3
inline fun <reified T : Any?> T?.case_3() {
contract { returns() implies (this@case_3 is Number && this@case_3 is Int && this@case_3 != null) }
contract { returns() implies (this@case_3 is Number && this@case_3 is Int && <!SENSELESS_COMPARISON!>this@case_3 != null<!>) }
if (!(this@case_3 is Number && this@case_3 is Int && <!SENSELESS_COMPARISON!>this@case_3 != null<!>)) throw Exception()
}
@@ -44,37 +44,37 @@ fun <T> T?.case_4_4(): Boolean? {
// TESTCASE NUMBER: 5
fun <T : Number?> T.case_5_1(): Boolean {
contract { returns(true) implies (this@case_5_1 is Int && this@case_5_1 != null) }
contract { returns(true) implies (this@case_5_1 is Int && <!SENSELESS_COMPARISON!>this@case_5_1 != null<!>) }
return this@case_5_1 is Int && <!SENSELESS_COMPARISON!>this@case_5_1 != null<!>
}
fun <T : Number?> T.case_5_2(): Boolean {
contract { returns(false) implies (this@case_5_2 is Int && this@case_5_2 != null) }
contract { returns(false) implies (this@case_5_2 is Int && <!SENSELESS_COMPARISON!>this@case_5_2 != null<!>) }
return !(this@case_5_2 is Int && <!SENSELESS_COMPARISON!>this@case_5_2 != null<!>)
}
fun <T : Number?> T.case_5_3(): Boolean? {
contract { returnsNotNull() implies (this@case_5_3 is Int && this@case_5_3 != null) }
contract { returnsNotNull() implies (this@case_5_3 is Int && <!SENSELESS_COMPARISON!>this@case_5_3 != null<!>) }
return if (this@case_5_3 is Int && <!SENSELESS_COMPARISON!>this@case_5_3 != null<!>) true else null
}
fun <T : Number?> T.case_5_4(): Boolean? {
contract { returns(null) implies (this@case_5_4 is Int && this@case_5_4 != null) }
contract { returns(null) implies (this@case_5_4 is Int && <!SENSELESS_COMPARISON!>this@case_5_4 != null<!>) }
return if (this@case_5_4 is Int && <!SENSELESS_COMPARISON!>this@case_5_4 != null<!>) null else true
}
// TESTCASE NUMBER: 6
inline fun <reified T : Any?> T?.case_6_1(): Boolean {
contract { returns(true) implies (this@case_6_1 is Number && this@case_6_1 is Int && this@case_6_1 != null) }
contract { returns(true) implies (this@case_6_1 is Number && this@case_6_1 is Int && <!SENSELESS_COMPARISON!>this@case_6_1 != null<!>) }
return this@case_6_1 is Number && this@case_6_1 is Int && <!SENSELESS_COMPARISON!>this@case_6_1 != null<!>
}
inline fun <reified T : Any?> T?.case_6_2(): Boolean {
contract { returns(false) implies (this@case_6_2 is Number && this@case_6_2 is Int && this@case_6_2 != null) }
contract { returns(false) implies (this@case_6_2 is Number && this@case_6_2 is Int && <!SENSELESS_COMPARISON!>this@case_6_2 != null<!>) }
return !(this@case_6_2 is Number && this@case_6_2 is Int && <!SENSELESS_COMPARISON!>this@case_6_2 != null<!>)
}
inline fun <reified T : Any?> T?.case_6_3(): Boolean? {
contract { returnsNotNull() implies (this@case_6_3 is Number && this@case_6_3 is Int && this@case_6_3 != null) }
contract { returnsNotNull() implies (this@case_6_3 is Number && this@case_6_3 is Int && <!SENSELESS_COMPARISON!>this@case_6_3 != null<!>) }
return if (this@case_6_3 is Number && this@case_6_3 is Int && <!SENSELESS_COMPARISON!>this@case_6_3 != null<!>) true else null
}
inline fun <reified T : Any?> T?.case_6_4(): Boolean? {
contract { returns(null) implies (this@case_6_4 is Number && this@case_6_4 is Int && this@case_6_4 != null) }
contract { returns(null) implies (this@case_6_4 is Number && this@case_6_4 is Int && <!SENSELESS_COMPARISON!>this@case_6_4 != null<!>) }
return if (this@case_6_4 is Number && this@case_6_4 is Int && <!SENSELESS_COMPARISON!>this@case_6_4 != null<!>) null else true
}
@@ -14,13 +14,13 @@ fun <T> T?.case_1(value_1: Int?) {
// TESTCASE NUMBER: 2
fun <T : Number?> T.case_2(value_2: Any?) {
contract { returns() implies (this@case_2 is Int && this@case_2 != null && value_2 is Number && value_2 != null) }
contract { returns() implies (this@case_2 is Int && <!SENSELESS_COMPARISON!>this@case_2 != null<!> && value_2 is Number && <!SENSELESS_COMPARISON!>value_2 != null<!>) }
if (!(this@case_2 is Int && <!SENSELESS_COMPARISON!>this@case_2 != null<!> && value_2 is Number && <!SENSELESS_COMPARISON!>value_2 != null<!>)) throw Exception()
}
// TESTCASE NUMBER: 3
fun <T : Any?> T?.case_3(value_2: Any?) {
contract { returns() implies (this@case_3 is Number && this@case_3 is Int && this@case_3 != null && value_2 != null) }
contract { returns() implies (this@case_3 is Number && this@case_3 is Int && <!SENSELESS_COMPARISON!>this@case_3 != null<!> && value_2 != null) }
if (!(this@case_3 is Number && this@case_3 is Int && <!SENSELESS_COMPARISON!>this@case_3 != null<!> && value_2 != null)) throw Exception()
}
@@ -50,37 +50,37 @@ fun <T> T?.case_5_4(value_1: Int?): Boolean? {
// TESTCASE NUMBER: 6
fun <T : Number?> T.case_6_1(value_2: Any?): Boolean {
contract { returns(true) implies (this@case_6_1 is Int && this@case_6_1 != null && value_2 is Number && value_2 != null) }
contract { returns(true) implies (this@case_6_1 is Int && <!SENSELESS_COMPARISON!>this@case_6_1 != null<!> && value_2 is Number && <!SENSELESS_COMPARISON!>value_2 != null<!>) }
return this@case_6_1 is Int && <!SENSELESS_COMPARISON!>this@case_6_1 != null<!> && value_2 is Number && <!SENSELESS_COMPARISON!>value_2 != null<!>
}
fun <T : Number?> T.case_6_2(value_2: Any?): Boolean {
contract { returns(false) implies (this@case_6_2 is Int && this@case_6_2 != null && value_2 is Number && value_2 != null) }
contract { returns(false) implies (this@case_6_2 is Int && <!SENSELESS_COMPARISON!>this@case_6_2 != null<!> && value_2 is Number && <!SENSELESS_COMPARISON!>value_2 != null<!>) }
return !(this@case_6_2 is Int && <!SENSELESS_COMPARISON!>this@case_6_2 != null<!> && value_2 is Number && <!SENSELESS_COMPARISON!>value_2 != null<!>)
}
fun <T : Number?> T.case_6_3(value_2: Any?): Boolean? {
contract { returnsNotNull() implies (this@case_6_3 is Int && this@case_6_3 != null && value_2 is Number && value_2 != null) }
contract { returnsNotNull() implies (this@case_6_3 is Int && <!SENSELESS_COMPARISON!>this@case_6_3 != null<!> && value_2 is Number && <!SENSELESS_COMPARISON!>value_2 != null<!>) }
return if (this@case_6_3 is Int && <!SENSELESS_COMPARISON!>this@case_6_3 != null<!> && value_2 is Number && <!SENSELESS_COMPARISON!>value_2 != null<!>) true else null
}
fun <T : Number?> T.case_6_4(value_2: Any?): Boolean? {
contract { returns(null) implies (this@case_6_4 is Int && this@case_6_4 != null && value_2 is Number && value_2 != null) }
contract { returns(null) implies (this@case_6_4 is Int && <!SENSELESS_COMPARISON!>this@case_6_4 != null<!> && value_2 is Number && <!SENSELESS_COMPARISON!>value_2 != null<!>) }
return if (this@case_6_4 is Int && <!SENSELESS_COMPARISON!>this@case_6_4 != null<!> && value_2 is Number && <!SENSELESS_COMPARISON!>value_2 != null<!>) null else true
}
// TESTCASE NUMBER: 7
fun <T : Any?> T?.case_7_1(value_2: Any?): Boolean {
contract { returns(true) implies (this@case_7_1 is Number && this@case_7_1 is Int && this@case_7_1 != null && value_2 != null) }
contract { returns(true) implies (this@case_7_1 is Number && this@case_7_1 is Int && <!SENSELESS_COMPARISON!>this@case_7_1 != null<!> && value_2 != null) }
return this@case_7_1 is Number && this@case_7_1 is Int && <!SENSELESS_COMPARISON!>this@case_7_1 != null<!> && value_2 != null
}
fun <T : Any?> T?.case_7_2(value_2: Any?): Boolean {
contract { returns(true) implies (this@case_7_2 is Number && this@case_7_2 is Int && this@case_7_2 != null && value_2 != null) }
contract { returns(true) implies (this@case_7_2 is Number && this@case_7_2 is Int && <!SENSELESS_COMPARISON!>this@case_7_2 != null<!> && value_2 != null) }
return this@case_7_2 is Number && this@case_7_2 is Int && <!SENSELESS_COMPARISON!>this@case_7_2 != null<!> && value_2 != null
}
fun <T : Any?> T?.case_7_3(value_2: Any?): Boolean? {
contract { returnsNotNull() implies (this@case_7_3 is Number && this@case_7_3 is Int && this@case_7_3 != null && value_2 != null) }
contract { returnsNotNull() implies (this@case_7_3 is Number && this@case_7_3 is Int && <!SENSELESS_COMPARISON!>this@case_7_3 != null<!> && value_2 != null) }
return if (this@case_7_3 is Number && this@case_7_3 is Int && <!SENSELESS_COMPARISON!>this@case_7_3 != null<!> && value_2 != null) true else null
}
fun <T : Any?> T?.case_7_4(value_2: Any?): Boolean? {
contract { returns(null) implies (this@case_7_4 is Number && this@case_7_4 is Int && this@case_7_4 != null && value_2 != null) }
contract { returns(null) implies (this@case_7_4 is Number && this@case_7_4 is Int && <!SENSELESS_COMPARISON!>this@case_7_4 != null<!> && value_2 != null) }
return if (this@case_7_4 is Number && this@case_7_4 is Int && <!SENSELESS_COMPARISON!>this@case_7_4 != null<!> && value_2 != null) null else true
}

Some files were not shown because too many files have changed in this diff Show More