[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); 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 @Nested
@TestMetadata("compiler/fir/analysis-tests/testData/resolveWithStdlib/contracts/fromSource/bad/callsInPlace") @TestMetadata("compiler/fir/analysis-tests/testData/resolveWithStdlib/contracts/fromSource/bad/callsInPlace")
@TestDataPath("$PROJECT_ROOT") @TestDataPath("$PROJECT_ROOT")
@@ -5247,6 +5253,12 @@ public class DiagnosisCompilerFirTestdataTestGenerated extends AbstractDiagnosis
public void testPropertyGetter() throws Exception { public void testPropertyGetter() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolveWithStdlib/contracts/fromSource/bad/returnsImplies/propertyGetter.kt"); 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) 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|>|() ^unknown R|<local>/x|.R|SubstitutionOverride<kotlin/Function0.invoke: R|T|>|()
} }
public final fun <T> atLeastOnce(x: R|() -> T|): R|T| public final fun <T> atLeastOnce(x: R|() -> T|): R|T|
@@ -14,7 +20,13 @@ FILE: flowFromInplaceLambda.kt
CallsInPlace(x, AT_LEAST_ONCE) 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|>|() ^atLeastOnce R|<local>/x|.R|SubstitutionOverride<kotlin/Function0.invoke: R|T|>|()
} }
public final fun <T> exactlyOnce(x: R|() -> T|): R|T| public final fun <T> exactlyOnce(x: R|() -> T|): R|T|
@@ -23,7 +35,13 @@ FILE: flowFromInplaceLambda.kt
CallsInPlace(x, EXACTLY_ONCE) 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|>|() ^exactlyOnce R|<local>/x|.R|SubstitutionOverride<kotlin/Function0.invoke: R|T|>|()
} }
public final fun <T> atMostOnce(x: R|() -> T|): R|T| public final fun <T> atMostOnce(x: R|() -> T|): R|T|
@@ -32,7 +50,13 @@ FILE: flowFromInplaceLambda.kt
CallsInPlace(x, AT_MOST_ONCE) 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|>|() ^atMostOnce R|<local>/x|.R|SubstitutionOverride<kotlin/Function0.invoke: R|T|>|()
} }
public final fun <T> noContract(x: R|() -> T|): R|T| { public final fun <T> noContract(x: R|() -> T|): R|T| {
@@ -1,4 +1,5 @@
// !DUMP_CFG // !DUMP_CFG
// !OPT_IN: kotlin.contracts.ExperimentalContracts
import kotlin.contracts.* import kotlin.contracts.*
@@ -9,350 +9,262 @@ digraph flowFromInplaceLambda3_kt {
subgraph cluster_1 { subgraph cluster_1 {
color=blue color=blue
1 [label="Enter block"]; 1 [label="Enter block"];
2 [label="Function call: R|<local>/x|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()" style="filled" fillcolor=yellow]; subgraph cluster_2 {
3 [label="Exit block"]; 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}; 0 -> {1};
1 -> {2}; 1 -> {2};
2 -> {3}; 2 -> {3};
3 -> {4}; 3 -> {4};
4 -> {5};
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];
}
5 -> {6}; 5 -> {6};
6 -> {7};
7 -> {8};
8 -> {9};
subgraph cluster_4 { subgraph cluster_3 {
color=red color=red
10 [label="Enter function exactlyOnce" style="filled" fillcolor=red]; 15 [label="Enter function atLeastOnce" style="filled" fillcolor=red];
subgraph cluster_5 { subgraph cluster_4 {
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 {
color=blue color=blue
16 [label="Enter block"]; 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}; 15 -> {16};
16 -> {17}; 16 -> {17};
17 -> {18}; 17 -> {18};
18 -> {19};
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];
}
19 -> {20}; 19 -> {20};
20 -> {21}; 20 -> {21};
21 -> {22};
22 -> {23}; subgraph cluster_6 {
23 -> {24}; color=red
24 -> {25}; 30 [label="Enter function exactlyOnce" style="filled" fillcolor=red];
25 -> {26}; subgraph cluster_7 {
26 -> {27}; color=blue
27 -> {28 38 29}; 31 [label="Enter block"];
27 -> {38} [style=dashed]; subgraph cluster_8 {
28 -> {29}; color=blue
28 -> {27} [color=green style=dashed]; 32 [label="Enter block"];
29 -> {30}; 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}; 30 -> {31};
31 -> {32}; 31 -> {32};
32 -> {33}; 32 -> {33};
33 -> {34}; 33 -> {34};
34 -> {35}; 34 -> {35};
35 -> {36}; 35 -> {36};
36 -> {37};
38 -> {39};
39 -> {40};
40 -> {41};
41 -> {42};
42 -> {43};
43 -> {28};
subgraph cluster_12 { subgraph cluster_9 {
color=red color=red
44 [label="Enter function test1m" style="filled" fillcolor=red]; 45 [label="Enter function atMostOnce" style="filled" fillcolor=red];
subgraph cluster_13 { subgraph cluster_10 {
color=blue color=blue
45 [label="Enter block"]; 46 [label="Enter block"];
46 [label="Variable declaration: lvar x: R|kotlin/Any?|"]; subgraph cluster_11 {
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 {
color=blue color=blue
60 [label="Enter function anonymousFunction" style="filled" fillcolor=red]; 47 [label="Enter block"];
subgraph cluster_15 { 48 [label="Exit block"];
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];
} }
53 [label="Postponed exit from lambda"]; 49 [label="Exit block"];
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"];
} }
59 [label="Exit function test1m" style="filled" fillcolor=red]; 50 [label="Exit function atMostOnce" style="filled" fillcolor=red];
} }
44 -> {45};
45 -> {46}; 45 -> {46};
46 -> {47}; 46 -> {47};
47 -> {48}; 47 -> {48};
48 -> {49}; 48 -> {49};
49 -> {50}; 49 -> {50};
50 -> {51};
51 -> {52}; subgraph cluster_12 {
52 -> {53 60 54}; color=red
52 -> {60} [style=dashed]; 59 [label="Enter function test1" style="filled" fillcolor=red];
53 -> {54}; subgraph cluster_13 {
53 -> {52} [color=green style=dashed]; color=blue
54 -> {55}; 60 [label="Enter block"];
55 -> {56}; 61 [label="Variable declaration: lvar x: R|kotlin/Any?|"];
56 -> {57}; 62 [label="Const: String()"];
57 -> {58}; 63 [label="Assignment: R|<local>/x|"];
58 -> {59}; 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}; 60 -> {61};
61 -> {62}; 61 -> {62};
62 -> {63}; 62 -> {63};
63 -> {64}; 63 -> {64};
64 -> {65}; 64 -> {65};
65 -> {53}; 65 -> {66};
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];
}
66 -> {67}; 66 -> {67};
67 -> {68}; 67 -> {68 78 69};
67 -> {78} [style=dashed];
68 -> {69}; 68 -> {69};
68 -> {67} [color=green style=dashed];
69 -> {70}; 69 -> {70};
70 -> {71}; 70 -> {71};
71 -> {72}; 71 -> {72};
72 -> {73}; 72 -> {73};
73 -> {74}; 73 -> {74};
74 -> {85 76}; 74 -> {75};
74 -> {75} [style=dotted];
74 -> {85} [style=dashed];
75 -> {76}; 75 -> {76};
75 -> {74} [color=green style=dashed];
76 -> {77}; 76 -> {77};
77 -> {78};
78 -> {79}; 78 -> {79};
79 -> {80}; 79 -> {80};
80 -> {81}; 80 -> {81};
81 -> {82}; 81 -> {82};
82 -> {83}; 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}; 85 -> {86};
86 -> {87}; 86 -> {87};
87 -> {88}; 87 -> {88};
88 -> {89}; 88 -> {89};
89 -> {90}; 89 -> {90};
90 -> {75}; 90 -> {91};
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];
}
91 -> {92}; 91 -> {92};
92 -> {93}; 92 -> {93 100 94};
92 -> {100} [style=dashed];
93 -> {94}; 93 -> {94};
93 -> {92} [color=green style=dashed];
94 -> {95}; 94 -> {95};
95 -> {96}; 95 -> {96};
96 -> {97}; 96 -> {97};
97 -> {98}; 97 -> {98};
98 -> {99}; 98 -> {99};
99 -> {110 101};
99 -> {100} [style=dotted];
99 -> {110} [style=dashed];
100 -> {101}; 100 -> {101};
101 -> {102}; 101 -> {102};
102 -> {103}; 102 -> {103};
103 -> {104}; 103 -> {104};
104 -> {105}; 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}; 106 -> {107};
107 -> {108}; 107 -> {108};
108 -> {109}; 108 -> {109};
109 -> {110};
110 -> {111}; 110 -> {111};
111 -> {112}; 111 -> {112};
112 -> {113}; 112 -> {113};
113 -> {114}; 113 -> {114};
114 -> {115}; 114 -> {125 116};
115 -> {100}; 114 -> {115} [style=dotted];
114 -> {125} [style=dashed];
subgraph cluster_24 { 115 -> {116};
color=red 115 -> {114} [color=green style=dashed];
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];
}
116 -> {117}; 116 -> {117};
117 -> {118}; 117 -> {118};
118 -> {119}; 118 -> {119};
@@ -361,22 +273,138 @@ digraph flowFromInplaceLambda3_kt {
121 -> {122}; 121 -> {122};
122 -> {123}; 122 -> {123};
123 -> {124}; 123 -> {124};
124 -> {125 135 126};
124 -> {135} [style=dashed];
125 -> {126}; 125 -> {126};
126 -> {127}; 126 -> {127};
127 -> {128}; 127 -> {128};
128 -> {129}; 128 -> {129};
129 -> {130}; 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}; 131 -> {132};
132 -> {133}; 132 -> {133};
133 -> {134}; 133 -> {134};
134 -> {135};
135 -> {136}; 135 -> {136};
136 -> {137}; 136 -> {137};
137 -> {138}; 137 -> {138};
138 -> {139}; 138 -> {139};
139 -> {140}; 139 -> {150 141};
140 -> {125}; 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) 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|>|() R|<local>/x|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()
} }
public final fun atLeastOnce(x: R|() -> kotlin/Unit|): 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) 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|<local>/x|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()
} }
public final fun exactlyOnce(x: R|() -> kotlin/Unit|): 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) 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|<local>/x|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()
} }
public final fun atMostOnce(x: R|() -> kotlin/Unit|): 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) 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| { public final fun test1(): R|kotlin/Unit| {
lvar x: R|kotlin/Any?| lvar x: R|kotlin/Any?|
@@ -1,4 +1,5 @@
// !DUMP_CFG // !DUMP_CFG
// !OPT_IN: kotlin.contracts.ExperimentalContracts
import kotlin.contracts.* 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?| { public final fun <T> n(): R|T?| {
^n Null(null) ^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] [R|Contract description]
< <
CallsInPlace(x, EXACTLY_ONCE) CallsInPlace(x, EXACTLY_ONCE)
CallsInPlace(y, 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>/x|.R|SubstitutionOverride<kotlin/Function0.invoke: R|T|>|()
R|<local>/y|.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 fun <T> n(): T? = null
@OptIn(ExperimentalContracts::class)
fun <T> run2(x: () -> T, y: () -> T) { fun <T> run2(x: () -> T, y: () -> T) {
contract { contract {
callsInPlace(x, InvocationKind.EXACTLY_ONCE) callsInPlace(x, InvocationKind.EXACTLY_ONCE)
@@ -25,15 +25,20 @@ digraph postponedLambdaInReturn_kt {
subgraph cluster_3 { subgraph cluster_3 {
color=blue color=blue
6 [label="Enter block"]; 6 [label="Enter block"];
7 [label="Function call: R|/Lateinit.Lateinit|<R|R|>()" style="filled" fillcolor=yellow]; subgraph cluster_4 {
8 [label="Access variable R|<local>/builder|"]; color=blue
9 [label="Function call: R|/Lateinit.Lateinit|<R|R|>().R|kotlin/apply|<R|Lateinit<R>|>(...)" style="filled" fillcolor=yellow]; 7 [label="Enter block"];
10 [label="Access variable R|SubstitutionOverride</Lateinit.value: R|R|>|"]; 8 [label="Exit block"];
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]; 9 [label="Function call: R|/Lateinit.Lateinit|<R|R|>()" style="filled" fillcolor=yellow];
13 [label="Exit block" style="filled" fillcolor=gray]; 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}; 5 -> {6};
6 -> {7}; 6 -> {7};
@@ -41,450 +46,452 @@ digraph postponedLambdaInReturn_kt {
8 -> {9}; 8 -> {9};
9 -> {10}; 9 -> {10};
10 -> {11}; 10 -> {11};
11 -> {14}; 11 -> {12};
11 -> {12} [style=dotted]; 12 -> {13};
12 -> {13} [style=dotted]; 13 -> {16};
13 -> {14} [style=dotted]; 13 -> {14} [style=dotted];
14 -> {15} [style=dotted];
subgraph cluster_4 { 15 -> {16} [style=dotted];
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};
subgraph cluster_5 { subgraph cluster_5 {
color=red color=red
18 [label="Enter function test1" style="filled" fillcolor=red]; 25 [label="Enter property" style="filled" fillcolor=red];
subgraph cluster_6 { 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 color=blue
19 [label="Enter block"]; 29 [label="Enter block"];
20 [label="Const: Null(null)"]; 30 [label="Const: Null(null)"];
21 [label="Variable declaration: lvar y: R|kotlin/String?|"]; 31 [label="Variable declaration: lvar y: R|kotlin/String?|"];
22 [label="Postponed enter to lambda"]; 32 [label="Postponed enter to lambda"];
subgraph cluster_7 { subgraph cluster_8 {
color=blue color=blue
30 [label="Enter function anonymousFunction" style="filled" fillcolor=red]; 40 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
subgraph cluster_8 { subgraph cluster_9 {
color=blue color=blue
31 [label="Enter block"]; 41 [label="Enter block"];
subgraph cluster_9 { subgraph cluster_10 {
color=blue color=blue
32 [label="Enter when"]; 42 [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"];
}
subgraph cluster_11 { subgraph cluster_11 {
color=blue color=blue
36 [label="Enter when branch condition else"]; 43 [label="Enter when branch condition "];
37 [label="Exit when branch condition"]; 44 [label="Access variable R|/p|"];
45 [label="Exit when branch condition"];
} }
38 [label="Enter when branch result"];
subgraph cluster_12 { subgraph cluster_12 {
color=blue color=blue
39 [label="Enter block"]; 46 [label="Enter when branch condition else"];
40 [label="Const: String()"]; 47 [label="Exit when branch condition"];
41 [label="Jump: ^@run String()"];
42 [label="Stub" style="filled" fillcolor=gray];
43 [label="Exit block" style="filled" fillcolor=gray];
} }
44 [label="Exit when branch result" style="filled" fillcolor=gray]; 48 [label="Enter when branch result"];
45 [label="Enter when branch result"];
subgraph cluster_13 { subgraph cluster_13 {
color=blue color=blue
46 [label="Enter block"]; 49 [label="Enter block"];
47 [label="Postponed enter to lambda"]; 50 [label="Const: String()"];
subgraph cluster_14 { 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 color=blue
57 [label="Enter function anonymousFunction" style="filled" fillcolor=red]; 67 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
subgraph cluster_15 { subgraph cluster_16 {
color=blue color=blue
58 [label="Enter block"]; 68 [label="Enter block"];
59 [label="Access variable R|<local>/y|"]; 69 [label="Access variable R|<local>/y|"];
60 [label="Type operator: (R|<local>/y| as R|kotlin/String|)"]; 70 [label="Type operator: (R|<local>/y| as R|kotlin/String|)"];
61 [label="Const: String(...)"]; 71 [label="Const: String(...)"];
62 [label="Assignment: R|SubstitutionOverride</Lateinit.value: R|kotlin/String|>|"]; 72 [label="Assignment: R|SubstitutionOverride</Lateinit.value: R|kotlin/String|>|"];
63 [label="Exit block"]; 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"]; 58 [label="Postponed exit from lambda"];
49 [label="Function call: R|/build|<R|kotlin/String|>(...)" style="filled" fillcolor=yellow]; 59 [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> { 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|) (R|<local>/y| as R|kotlin/String|)
this@R|special/anonymous|.R|SubstitutionOverride</Lateinit.value: R|kotlin/String|>| = String(...) this@R|special/anonymous|.R|SubstitutionOverride</Lateinit.value: R|kotlin/String|>| = String(...)
} }
)"]; )"];
51 [label="Stub" style="filled" fillcolor=gray]; 61 [label="Stub" style="filled" fillcolor=gray];
52 [label="Exit block" style="filled" fillcolor=gray]; 62 [label="Exit block" style="filled" fillcolor=gray];
} }
53 [label="Exit when branch result" style="filled" fillcolor=gray]; 63 [label="Exit when branch result" style="filled" fillcolor=gray];
54 [label="Exit when" 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"]; 33 [label="Postponed exit from lambda"];
24 [label="Function call: R|kotlin/run|<R|kotlin/String|>(...)" style="filled" fillcolor=yellow]; 34 [label="Function call: R|kotlin/run|<R|kotlin/String|>(...)" style="filled" fillcolor=yellow];
25 [label="Variable declaration: lval x: R|kotlin/String|"]; 35 [label="Variable declaration: lval x: R|kotlin/String|"];
26 [label="Access variable R|<local>/y|"]; 36 [label="Access variable R|<local>/y|"];
27 [label="Access variable R|kotlin/String.length<Inapplicable(UNSAFE_CALL): kotlin/String.length>#|"]; 37 [label="Access variable R|kotlin/String.length<Inapplicable(UNSAFE_CALL): kotlin/String.length>#|"];
28 [label="Exit block"]; 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}; 28 -> {29};
29 -> {30};
30 -> {31}; 30 -> {31};
31 -> {32}; 31 -> {32};
32 -> {33}; 32 -> {40 34};
32 -> {33} [style=dotted];
32 -> {40} [style=dashed];
33 -> {34}; 33 -> {34};
34 -> {35}; 34 -> {35};
35 -> {45 36}; 35 -> {36};
36 -> {37}; 36 -> {37};
37 -> {38}; 37 -> {38};
38 -> {39}; 38 -> {39};
39 -> {40};
40 -> {41}; 40 -> {41};
41 -> {56}; 41 -> {42};
41 -> {42} [style=dotted]; 42 -> {43};
42 -> {43} [style=dotted]; 43 -> {44};
43 -> {44} [style=dotted]; 44 -> {45};
44 -> {54} [style=dotted]; 45 -> {55 46};
45 -> {46};
46 -> {47}; 46 -> {47};
47 -> {49 57}; 47 -> {48};
47 -> {48} [style=dotted]; 48 -> {49};
47 -> {57} [style=dashed];
48 -> {49} [color=green];
49 -> {50}; 49 -> {50};
50 -> {56}; 50 -> {51};
50 -> {51} [style=dotted]; 51 -> {66};
51 -> {52} [style=dotted]; 51 -> {52} [style=dotted];
52 -> {53} [style=dotted]; 52 -> {53} [style=dotted];
53 -> {54} [style=dotted]; 53 -> {54} [style=dotted];
54 -> {55} [style=dotted]; 54 -> {64} [style=dotted];
55 -> {56} [style=dotted]; 55 -> {56};
56 -> {23}; 56 -> {57};
57 -> {58}; 57 -> {59 67};
58 -> {59}; 57 -> {58} [style=dotted];
57 -> {67} [style=dashed];
58 -> {59} [color=green];
59 -> {60}; 59 -> {60};
60 -> {61}; 60 -> {66};
61 -> {62}; 60 -> {61} [style=dotted];
62 -> {63}; 61 -> {62} [style=dotted];
63 -> {64}; 62 -> {63} [style=dotted];
64 -> {48}; 63 -> {64} [style=dotted];
64 -> {65} [style=dotted];
subgraph cluster_16 { 65 -> {66} [style=dotted];
color=red 66 -> {33};
65 [label="Enter function test2" style="filled" fillcolor=red]; 67 -> {68};
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];
68 -> {69}; 68 -> {69};
69 -> {70}; 69 -> {70};
70 -> {71}; 70 -> {71};
71 -> {72}; 71 -> {72};
72 -> {73}; 72 -> {73};
73 -> {74}; 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}; 75 -> {76};
76 -> {77}; 76 -> {77};
77 -> {78}; 77 -> {85 79};
77 -> {78} [style=dotted];
77 -> {85} [style=dashed];
78 -> {79}; 78 -> {79};
79 -> {80}; 79 -> {80};
80 -> {81}; 80 -> {81};
80 -> {101} [style=dotted];
81 -> {82}; 81 -> {82};
82 -> {83}; 82 -> {83};
83 -> {84 93}; 83 -> {84};
84 -> {85};
85 -> {86}; 85 -> {86};
86 -> {88 107}; 86 -> {87};
86 -> {87} [style=dotted]; 87 -> {88};
86 -> {107} [style=dashed];
87 -> {88} [color=green];
88 -> {89}; 88 -> {89};
89 -> {106}; 89 -> {90};
89 -> {90} [style=dotted]; 90 -> {91};
90 -> {91} [style=dotted]; 90 -> {111} [style=dotted];
91 -> {92} [style=dotted]; 91 -> {92};
92 -> {98 93} [style=dotted]; 92 -> {93};
93 -> {94}; 93 -> {94 103};
93 -> {74} [label=onUncaughtException];
94 -> {95}; 94 -> {95};
95 -> {96}; 95 -> {96};
96 -> {97}; 96 -> {98 117};
97 -> {98}; 96 -> {97} [style=dotted];
96 -> {117} [style=dashed];
97 -> {98} [color=green];
98 -> {99}; 98 -> {99};
99 -> {100}; 99 -> {116};
100 -> {78} [color=green style=dashed]; 99 -> {100} [style=dotted];
100 -> {101} [style=dotted];
101 -> {102} [style=dotted]; 101 -> {102} [style=dotted];
102 -> {103} [style=dotted]; 102 -> {108 103} [style=dotted];
103 -> {104} [style=dotted]; 103 -> {104};
103 -> {74} [style=dotted] [label=onUncaughtException]; 103 -> {84} [label=onUncaughtException];
104 -> {105} [style=dotted]; 104 -> {105};
105 -> {106} [style=dotted]; 105 -> {106};
106 -> {68}; 106 -> {107};
107 -> {108}; 107 -> {108};
108 -> {109}; 108 -> {109};
109 -> {110}; 109 -> {110};
110 -> {111}; 110 -> {88} [color=green style=dashed];
111 -> {112}; 111 -> {112} [style=dotted];
112 -> {87}; 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 color=red
113 [label="Enter function test3" style="filled" fillcolor=red]; 123 [label="Enter function test3" style="filled" fillcolor=red];
subgraph cluster_32 { subgraph cluster_33 {
color=blue color=blue
114 [label="Enter block"]; 124 [label="Enter block"];
115 [label="Variable declaration: lvar y: R|kotlin/String?|"]; 125 [label="Variable declaration: lvar y: R|kotlin/String?|"];
116 [label="Const: String()"]; 126 [label="Const: String()"];
117 [label="Assignment: R|<local>/y|"]; 127 [label="Assignment: R|<local>/y|"];
118 [label="Postponed enter to lambda"]; 128 [label="Postponed enter to lambda"];
subgraph cluster_33 { subgraph cluster_34 {
color=blue color=blue
127 [label="Enter function anonymousFunction" style="filled" fillcolor=red]; 137 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
subgraph cluster_34 { subgraph cluster_35 {
color=blue color=blue
128 [label="Enter block"]; 138 [label="Enter block"];
subgraph cluster_35 { subgraph cluster_36 {
color=blue color=blue
129 [label="Enter when"]; 139 [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"];
}
subgraph cluster_37 { subgraph cluster_37 {
color=blue color=blue
134 [label="Enter when branch condition else"]; 140 [label="Enter when branch condition "];
135 [label="Exit 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 { subgraph cluster_38 {
color=blue color=blue
137 [label="Enter block"]; 144 [label="Enter when branch condition else"];
138 [label="Const: String()"]; 145 [label="Exit when branch condition"];
139 [label="Jump: ^@run String()"];
140 [label="Stub" style="filled" fillcolor=gray];
141 [label="Exit block" style="filled" fillcolor=gray];
} }
142 [label="Exit when branch result" style="filled" fillcolor=gray]; 146 [label="Enter when branch result"];
143 [label="Enter when branch result"];
subgraph cluster_39 { subgraph cluster_39 {
color=blue color=blue
144 [label="Enter block"]; 147 [label="Enter block"];
145 [label="Postponed enter to lambda"]; 148 [label="Const: String()"];
subgraph cluster_40 { 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 color=blue
155 [label="Enter function anonymousFunction" style="filled" fillcolor=red]; 165 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
subgraph cluster_41 { subgraph cluster_42 {
color=blue color=blue
156 [label="Enter block"]; 166 [label="Enter block"];
157 [label="Const: Null(null)"]; 167 [label="Const: Null(null)"];
158 [label="Assignment: R|<local>/y|"]; 168 [label="Assignment: R|<local>/y|"];
159 [label="Const: String(...)"]; 169 [label="Const: String(...)"];
160 [label="Assignment: R|SubstitutionOverride</Lateinit.value: R|kotlin/String|>|"]; 170 [label="Assignment: R|SubstitutionOverride</Lateinit.value: R|kotlin/String|>|"];
161 [label="Exit block"]; 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"]; 156 [label="Postponed exit from lambda"];
147 [label="Function call: R|/build|<R|kotlin/String|>(...)" style="filled" fillcolor=yellow]; 157 [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> { 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) R|<local>/y| = Null(null)
this@R|special/anonymous|.R|SubstitutionOverride</Lateinit.value: R|kotlin/String|>| = String(...) this@R|special/anonymous|.R|SubstitutionOverride</Lateinit.value: R|kotlin/String|>| = String(...)
} }
)"]; )"];
149 [label="Stub" style="filled" fillcolor=gray]; 159 [label="Stub" style="filled" fillcolor=gray];
150 [label="Exit block" style="filled" fillcolor=gray]; 160 [label="Exit block" style="filled" fillcolor=gray];
} }
151 [label="Exit when branch result" style="filled" fillcolor=gray]; 161 [label="Exit when branch result" style="filled" fillcolor=gray];
152 [label="Exit when" 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"]; 129 [label="Postponed exit from lambda"];
120 [label="Function call: R|kotlin/run|<R|kotlin/String|>(...)" style="filled" fillcolor=yellow]; 130 [label="Function call: R|kotlin/run|<R|kotlin/String|>(...)" style="filled" fillcolor=yellow];
121 [label="Variable declaration: lval x: R|kotlin/String|"]; 131 [label="Variable declaration: lval x: R|kotlin/String|"];
122 [label="Access variable R|<local>/y|"]; 132 [label="Access variable R|<local>/y|"];
123 [label="Smart cast: R|<local>/y|"]; 133 [label="Smart cast: R|<local>/y|"];
124 [label="Access variable R|kotlin/String.length|"]; 134 [label="Access variable R|kotlin/String.length|"];
125 [label="Exit block"]; 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}; 123 -> {124};
124 -> {125}; 124 -> {125};
125 -> {126}; 125 -> {126};
126 -> {127};
127 -> {128}; 127 -> {128};
128 -> {129}; 128 -> {137 130};
128 -> {129} [style=dotted];
128 -> {137} [style=dashed];
129 -> {130}; 129 -> {130};
130 -> {131}; 130 -> {131};
131 -> {132}; 131 -> {132};
132 -> {133}; 132 -> {133};
133 -> {143 134}; 133 -> {134};
134 -> {135}; 134 -> {135};
135 -> {136}; 135 -> {136};
136 -> {137};
137 -> {138}; 137 -> {138};
138 -> {139}; 138 -> {139};
139 -> {154}; 139 -> {140};
139 -> {140} [style=dotted]; 140 -> {141};
140 -> {141} [style=dotted]; 141 -> {142};
141 -> {142} [style=dotted]; 142 -> {143};
142 -> {152} [style=dotted]; 143 -> {153 144};
143 -> {144};
144 -> {145}; 144 -> {145};
145 -> {147 155}; 145 -> {146};
145 -> {146} [style=dotted]; 146 -> {147};
145 -> {155} [style=dashed];
146 -> {147} [color=green];
147 -> {148}; 147 -> {148};
148 -> {154}; 148 -> {149};
148 -> {149} [style=dotted]; 149 -> {164};
149 -> {150} [style=dotted]; 149 -> {150} [style=dotted];
150 -> {151} [style=dotted]; 150 -> {151} [style=dotted];
151 -> {152} [style=dotted]; 151 -> {152} [style=dotted];
152 -> {153} [style=dotted]; 152 -> {162} [style=dotted];
153 -> {154} [style=dotted]; 153 -> {154};
154 -> {119}; 154 -> {155};
155 -> {156}; 155 -> {157 165};
156 -> {157}; 155 -> {156} [style=dotted];
155 -> {165} [style=dashed];
156 -> {157} [color=green];
157 -> {158}; 157 -> {158};
158 -> {159}; 158 -> {164};
159 -> {160}; 158 -> {159} [style=dotted];
160 -> {161}; 159 -> {160} [style=dotted];
161 -> {162}; 160 -> {161} [style=dotted];
162 -> {146}; 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) 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|>| ^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) public final val p: R|kotlin/Boolean| = Boolean(false)
@@ -9,100 +9,107 @@ digraph inAnonymousObject_kt {
subgraph cluster_1 { subgraph cluster_1 {
color=blue color=blue
1 [label="Enter block"]; 1 [label="Enter block"];
2 [label="Enter anonymous object"];
subgraph cluster_2 { subgraph cluster_2 {
color=blue color=blue
11 [label="Enter class <anonymous object>" style="filled" fillcolor=red]; 2 [label="Enter block"];
12 [label="Part of class initialization"]; 3 [label="Exit block"];
13 [label="Part of class initialization"];
14 [label="Exit class <anonymous object>" style="filled" fillcolor=red];
} }
3 [label="Exit anonymous object"]; 4 [label="Enter anonymous object"];
4 [label="Exit anonymous object expression"]; subgraph cluster_3 {
5 [label="Variable declaration: lval obj: R|<anonymous>|"]; color=blue
6 [label="Access variable R|<local>/obj|"]; 13 [label="Enter class <anonymous object>" style="filled" fillcolor=red];
7 [label="Function call: R|<local>/obj|.R|/<anonymous>.run|()" style="filled" fillcolor=yellow]; 14 [label="Part of class initialization"];
8 [label="Function call: R|<local>/d|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()" style="filled" fillcolor=yellow]; 15 [label="Part of class initialization"];
9 [label="Exit block"]; 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}; 0 -> {1};
1 -> {2}; 1 -> {2};
1 -> {15 18 21 27} [color=red]; 2 -> {3};
2 -> {3} [color=red];
2 -> {11} [color=green];
2 -> {11} [style=dashed];
3 -> {4}; 3 -> {4};
3 -> {15 27} [color=green]; 3 -> {37 40 43 49} [color=red];
3 -> {15 27} [style=dashed]; 4 -> {5} [color=red];
4 -> {5}; 4 -> {13} [color=green];
4 -> {13} [style=dashed];
5 -> {6}; 5 -> {6};
5 -> {37 49} [color=green];
5 -> {37 49} [style=dashed];
6 -> {7}; 6 -> {7};
7 -> {8}; 7 -> {8};
8 -> {9}; 8 -> {9};
9 -> {10}; 9 -> {10};
11 -> {12} [color=green]; 10 -> {11};
12 -> {13} [style=dotted]; 11 -> {12};
12 -> {18} [color=green]; 13 -> {14} [color=green];
12 -> {18} [style=dashed]; 14 -> {15} [style=dotted];
13 -> {14} [style=dotted]; 14 -> {40} [color=green];
13 -> {21} [color=green]; 14 -> {40} [style=dashed];
13 -> {21} [style=dashed]; 15 -> {16} [style=dotted];
14 -> {3} [color=green]; 15 -> {43} [color=green];
15 -> {43} [style=dashed];
subgraph cluster_3 { 16 -> {5} [color=green];
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};
subgraph cluster_4 { subgraph cluster_4 {
color=red color=red
18 [label="Enter property" style="filled" fillcolor=red]; 37 [label="Enter function <init>" style="filled" fillcolor=red];
19 [label="Access variable R|<local>/a|"]; 38 [label="Delegated constructor call: super<R|kotlin/Any|>()" style="filled" fillcolor=yellow];
20 [label="Exit property" style="filled" fillcolor=red]; 39 [label="Exit function <init>" style="filled" fillcolor=red];
} }
18 -> {19}; 37 -> {38};
19 -> {20}; 38 -> {39};
20 -> {13} [color=green];
subgraph cluster_5 { subgraph cluster_5 {
color=red color=red
21 [label="Enter init block" style="filled" fillcolor=red]; 40 [label="Enter property" style="filled" fillcolor=red];
subgraph cluster_6 { 41 [label="Access variable R|<local>/a|"];
color=blue 42 [label="Exit property" style="filled" fillcolor=red];
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];
} }
21 -> {22}; 40 -> {41};
22 -> {23}; 41 -> {42};
23 -> {24}; 42 -> {15} [color=green];
24 -> {25};
25 -> {26};
26 -> {14} [color=green];
subgraph cluster_7 { subgraph cluster_6 {
color=red color=red
27 [label="Enter function run" style="filled" fillcolor=red]; 43 [label="Enter init block" style="filled" fillcolor=red];
subgraph cluster_8 { subgraph cluster_7 {
color=blue color=blue
28 [label="Enter block"]; 44 [label="Enter block"];
29 [label="Function call: R|<local>/c|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()" style="filled" fillcolor=yellow]; 45 [label="Access variable R|<local>/b|"];
30 [label="Exit block"]; 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}; 43 -> {44};
28 -> {29}; 44 -> {45};
29 -> {30}; 45 -> {46};
30 -> {31}; 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) 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| { lval obj: R|<anonymous>| = object : R|java/lang/Runnable| {
private constructor(): R|<anonymous>| { private constructor(): R|<anonymous>| {
super<R|kotlin/Any|>() super<R|kotlin/Any|>()
@@ -9,100 +9,107 @@ digraph inLocalClass_kt {
subgraph cluster_1 { subgraph cluster_1 {
color=blue color=blue
1 [label="Enter block"]; 1 [label="Enter block"];
2 [label="Exit local class foo"]; subgraph cluster_2 {
3 [label="Function call: R|/LocalClass.LocalClass|()" style="filled" fillcolor=yellow]; color=blue
4 [label="Function call: R|/LocalClass.LocalClass|().R|<local>/run|()" style="filled" fillcolor=yellow]; 2 [label="Enter block"];
5 [label="Function call: R|<local>/e|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()" style="filled" fillcolor=yellow]; 3 [label="Exit block"];
6 [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 color=blue
8 [label="Enter class LocalClass" style="filled" fillcolor=red]; 10 [label="Enter class LocalClass" style="filled" fillcolor=red];
9 [label="Part of class initialization"]; 11 [label="Part of class initialization"];
10 [label="Part of class initialization"]; 12 [label="Part of class initialization"];
11 [label="Exit class LocalClass" style="filled" fillcolor=red]; 13 [label="Exit class LocalClass" style="filled" fillcolor=red];
} }
0 -> {1}; 0 -> {1};
1 -> {2}; 1 -> {2};
1 -> {12 15 21 27} [color=red];
2 -> {3}; 2 -> {3};
2 -> {15 27 8} [color=green];
2 -> {15 27 8} [style=dashed];
3 -> {4}; 3 -> {4};
3 -> {38 41 47 53} [color=red];
4 -> {5}; 4 -> {5};
4 -> {41 53 10} [color=green];
4 -> {41 53 10} [style=dashed];
5 -> {6}; 5 -> {6};
6 -> {7}; 6 -> {7};
8 -> {9} [color=green]; 7 -> {8};
9 -> {10} [style=dotted]; 8 -> {9};
9 -> {12} [color=green]; 10 -> {11} [color=green];
9 -> {12} [style=dashed]; 11 -> {12} [style=dotted];
10 -> {11} [style=dotted]; 11 -> {38} [color=green];
10 -> {21} [color=green]; 11 -> {38} [style=dashed];
10 -> {21} [style=dashed]; 12 -> {13} [style=dotted];
12 -> {47} [color=green];
subgraph cluster_3 { 12 -> {47} [style=dashed];
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];
subgraph cluster_4 { subgraph cluster_4 {
color=red color=red
15 [label="Enter function <init>" style="filled" fillcolor=red]; 38 [label="Enter property" style="filled" fillcolor=red];
16 [label="Delegated constructor call: super<R|kotlin/Any|>()" style="filled" fillcolor=yellow]; 39 [label="Access variable R|<local>/a|"];
subgraph cluster_5 { 40 [label="Exit property" style="filled" fillcolor=red];
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];
} }
15 -> {16}; 38 -> {39};
16 -> {17}; 39 -> {40};
17 -> {18}; 40 -> {12} [color=green];
18 -> {19};
19 -> {20};
subgraph cluster_6 { subgraph cluster_5 {
color=red color=red
21 [label="Enter init block" style="filled" fillcolor=red]; 41 [label="Enter function <init>" style="filled" fillcolor=red];
subgraph cluster_7 { 42 [label="Delegated constructor call: super<R|kotlin/Any|>()" style="filled" fillcolor=yellow];
subgraph cluster_6 {
color=blue color=blue
22 [label="Enter block"]; 43 [label="Enter block"];
23 [label="Access variable R|<local>/c|"]; 44 [label="Function call: R|<local>/b|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()" style="filled" fillcolor=yellow];
24 [label="Assignment: R|<local>/leaked|"]; 45 [label="Exit block"];
25 [label="Exit block"];
} }
26 [label="Exit init block" style="filled" fillcolor=red]; 46 [label="Exit function <init>" style="filled" fillcolor=red];
} }
21 -> {22}; 41 -> {42};
22 -> {23}; 42 -> {43};
23 -> {24}; 43 -> {44};
24 -> {25}; 44 -> {45};
25 -> {26}; 45 -> {46};
26 -> {11} [color=green];
subgraph cluster_8 { subgraph cluster_7 {
color=red color=red
27 [label="Enter function run" style="filled" fillcolor=red]; 47 [label="Enter init block" style="filled" fillcolor=red];
subgraph cluster_9 { subgraph cluster_8 {
color=blue color=blue
28 [label="Enter block"]; 48 [label="Enter block"];
29 [label="Function call: R|<local>/d|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()" style="filled" fillcolor=yellow]; 49 [label="Access variable R|<local>/c|"];
30 [label="Exit block"]; 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}; 47 -> {48};
28 -> {29}; 48 -> {49};
29 -> {30}; 49 -> {50};
30 -> {31}; 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) 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| { local final class LocalClass : R|kotlin/Any| {
public final val leakedVal: R|() -> kotlin/Unit| = R|<local>/a| public final val leakedVal: R|() -> kotlin/Unit| = R|<local>/a|
public get(): R|() -> kotlin/Unit| public get(): R|() -> kotlin/Unit|
@@ -9,38 +9,45 @@ digraph inLocalFunction_kt {
subgraph cluster_1 { subgraph cluster_1 {
color=blue color=blue
1 [label="Enter block"]; 1 [label="Enter block"];
2 [label="Local function declaration foo"]; subgraph cluster_2 {
3 [label="Function call: R|<local>/localFun|()" style="filled" fillcolor=yellow]; color=blue
4 [label="Function call: R|<local>/b|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()" style="filled" fillcolor=yellow]; 2 [label="Enter block"];
5 [label="Exit 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 color=blue
7 [label="Enter function localFun" style="filled" fillcolor=red]; 9 [label="Enter function localFun" style="filled" fillcolor=red];
subgraph cluster_3 { subgraph cluster_4 {
color=blue color=blue
8 [label="Enter block"]; 10 [label="Enter block"];
9 [label="Access variable R|<local>/a|"]; 11 [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]; 12 [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]; 13 [label="Function call: R|<local>/a|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()" style="filled" fillcolor=yellow];
12 [label="Exit block"]; 14 [label="Exit block"];
} }
13 [label="Exit function localFun" style="filled" fillcolor=red]; 15 [label="Exit function localFun" style="filled" fillcolor=red];
} }
0 -> {1}; 0 -> {1};
1 -> {2}; 1 -> {2};
2 -> {7 3}; 2 -> {3};
2 -> {7} [style=dashed];
3 -> {4}; 3 -> {4};
4 -> {5}; 4 -> {9 5};
4 -> {9} [style=dashed];
5 -> {6}; 5 -> {6};
6 -> {7};
7 -> {8}; 7 -> {8};
8 -> {9};
9 -> {10}; 9 -> {10};
10 -> {11}; 10 -> {11};
11 -> {12}; 11 -> {12};
12 -> {13}; 12 -> {13};
13 -> {14};
14 -> {15};
} }
@@ -5,7 +5,13 @@ FILE: inLocalFunction.kt
CallsInPlace(a, AT_MOST_ONCE) 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| { 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|>|()
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"]; 5 [label="Enter block"];
subgraph cluster_4 { subgraph cluster_4 {
color=blue color=blue
6 [label="Enter when"]; 6 [label="Enter block"];
subgraph cluster_5 { 7 [label="Exit block"];
color=blue }
7 [label="Enter when branch condition "]; subgraph cluster_5 {
8 [label="Const: Boolean(true)"]; color=blue
9 [label="Exit when branch condition"]; 8 [label="Enter when"];
}
subgraph cluster_6 { subgraph cluster_6 {
color=blue 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"]; 11 [label="Exit when branch condition"];
} }
12 [label="Enter when branch result"];
subgraph cluster_7 { subgraph cluster_7 {
color=blue color=blue
13 [label="Enter block"]; 12 [label="Enter when branch condition else"];
14 [label="Access variable R|<local>/y|"]; 13 [label="Exit when branch condition"];
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"];
} }
18 [label="Exit when branch result"]; 14 [label="Enter when branch result"];
19 [label="Enter when branch result"];
subgraph cluster_8 { subgraph cluster_8 {
color=blue color=blue
20 [label="Enter block"]; 15 [label="Enter block"];
21 [label="Access variable R|<local>/x|"]; 16 [label="Access variable R|<local>/y|"];
22 [label="Function call: R|/bar|(...)" style="filled" fillcolor=yellow]; 17 [label="Variable declaration: lval yCopy: R|() -> kotlin/Unit|"];
23 [label="Exit block"]; 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"]; 20 [label="Exit when branch result"];
25 [label="Exit when"]; 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|"]; 28 [label="Variable declaration: lval zCopy: R|() -> kotlin/Unit|"];
27 [label="Access variable R|<local>/z|"]; 29 [label="Access variable R|<local>/z|"];
28 [label="Assignment: R|<local>/zCopy|"]; 30 [label="Assignment: R|<local>/zCopy|"];
29 [label="Function call: R|<local>/zCopy|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()" style="filled" fillcolor=yellow]; 31 [label="Function call: R|<local>/zCopy|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()" style="filled" fillcolor=yellow];
30 [label="Exit block"]; 32 [label="Exit block"];
} }
31 [label="Exit function foo" style="filled" fillcolor=red]; 33 [label="Exit function foo" style="filled" fillcolor=red];
} }
4 -> {5}; 4 -> {5};
5 -> {6}; 5 -> {6};
6 -> {7}; 6 -> {7};
7 -> {8}; 7 -> {8};
8 -> {9}; 8 -> {9};
9 -> {19 10}; 9 -> {10};
10 -> {11}; 10 -> {11};
11 -> {12}; 11 -> {21 12};
12 -> {13}; 12 -> {13};
13 -> {14}; 13 -> {14};
14 -> {15}; 14 -> {15};
15 -> {16}; 15 -> {16};
16 -> {17}; 16 -> {17};
17 -> {18}; 17 -> {18};
18 -> {25}; 18 -> {19};
19 -> {20}; 19 -> {20};
20 -> {21}; 20 -> {27};
21 -> {22}; 21 -> {22};
22 -> {23}; 22 -> {23};
23 -> {24}; 23 -> {24};
@@ -93,5 +98,7 @@ digraph toLocalVariables_kt {
28 -> {29}; 28 -> {29};
29 -> {30}; 29 -> {30};
30 -> {31}; 30 -> {31};
31 -> {32};
32 -> {33};
} }
@@ -9,7 +9,15 @@ FILE: toLocalVariables.kt
CallsInPlace(z, AT_MOST_ONCE) 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 () { when () {
Boolean(true) -> { Boolean(true) -> {
R|/bar|(R|<local>/x|) 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 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 () { when () {
Boolean(true) -> { Boolean(true) -> {
throw Q|java/lang|.R|java/lang/IllegalArgumentException.IllegalArgumentException|() throw Q|java/lang|.R|java/lang/IllegalArgumentException.IllegalArgumentException|()
@@ -20,7 +26,13 @@ FILE: notNull.kt
Returns(WILDCARD) -> x != null 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 () { when () {
==(R|<local>/x|, Null(null)) -> { ==(R|<local>/x|, Null(null)) -> {
^bar R|<local>/x| ^bar R|<local>/x|
@@ -35,6 +47,12 @@ FILE: notNull.kt
Returns(NULL) -> x != null 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| ^baz R|<local>/x|
} }
@@ -5,7 +5,13 @@ FILE: propertyGetter.kt
Returns(TRUE) -> this != null 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)) ^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| @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 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)) ^ !=(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 { subgraph cluster_1 {
color=blue color=blue
1 [label="Enter block"]; 1 [label="Enter block"];
2 [label="Function call: R|<local>/block|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()" style="filled" fillcolor=yellow]; subgraph cluster_2 {
3 [label="Exit block"]; 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}; 0 -> {1};
1 -> {2}; 1 -> {2};
2 -> {3}; 2 -> {3};
3 -> {4}; 3 -> {4};
4 -> {5};
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];
}
5 -> {6}; 5 -> {6};
6 -> {7};
7 -> {8};
8 -> {9};
subgraph cluster_4 { subgraph cluster_3 {
color=red color=red
10 [label="Enter function test_1" style="filled" fillcolor=red]; 15 [label="Enter function myRun" style="filled" fillcolor=red];
subgraph cluster_5 { subgraph cluster_4 {
color=blue color=blue
11 [label="Enter block"]; 16 [label="Enter block"];
12 [label="Variable declaration: lval x: R|kotlin/Int|"]; subgraph cluster_5 {
13 [label="Postponed enter to lambda"];
subgraph cluster_6 {
color=blue color=blue
20 [label="Enter function anonymousFunction" style="filled" fillcolor=red]; 17 [label="Enter block"];
subgraph cluster_7 { 18 [label="Exit block"];
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];
} }
14 [label="Postponed exit from lambda"]; 19 [label="Function call: R|<local>/block|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()" style="filled" fillcolor=yellow];
15 [label="Function call: R|/inlineRun|(...)" style="filled" fillcolor=yellow]; 20 [label="Exit block"];
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="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}; 15 -> {16};
16 -> {17}; 16 -> {17};
17 -> {18}; 17 -> {18};
18 -> {19}; 18 -> {19};
19 -> {20};
20 -> {21}; 20 -> {21};
21 -> {22};
22 -> {23};
23 -> {24};
24 -> {25};
25 -> {14};
subgraph cluster_8 { subgraph cluster_6 {
color=red color=red
26 [label="Enter function test_2" style="filled" fillcolor=red]; 30 [label="Enter function test_1" style="filled" fillcolor=red];
subgraph cluster_9 { subgraph cluster_7 {
color=blue color=blue
27 [label="Enter block"]; 31 [label="Enter block"];
28 [label="Variable declaration: lval x: R|kotlin/Int|"]; 32 [label="Variable declaration: lval x: R|kotlin/Int|"];
29 [label="Postponed enter to lambda"]; 33 [label="Postponed enter to lambda"];
subgraph cluster_10 { subgraph cluster_8 {
color=blue color=blue
36 [label="Enter function anonymousFunction" style="filled" fillcolor=red]; 40 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
subgraph cluster_11 { subgraph cluster_9 {
color=blue color=blue
37 [label="Enter block"]; 41 [label="Enter block"];
38 [label="Const: Int(1)"]; 42 [label="Const: Int(1)"];
39 [label="Assignment: R|<local>/x|"]; 43 [label="Assignment: R|<local>/x|"];
40 [label="Exit block"]; 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"]; 34 [label="Postponed exit from lambda"];
31 [label="Function call: R|/myRun|(...)" style="filled" fillcolor=yellow]; 35 [label="Function call: R|/inlineRun|(...)" style="filled" fillcolor=yellow];
32 [label="Access variable R|<local>/x|"]; 36 [label="Access variable R|<local>/x|"];
33 [label="Function call: R|<local>/x|.R|kotlin/Int.inc|()" style="filled" fillcolor=yellow]; 37 [label="Function call: R|<local>/x|.R|kotlin/Int.inc|()" style="filled" fillcolor=yellow];
34 [label="Exit block"]; 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 -> {31};
30 -> {29} [color=green style=dashed];
31 -> {32}; 31 -> {32};
32 -> {33}; 32 -> {33};
33 -> {34}; 33 -> {40 35};
33 -> {34} [style=dotted];
33 -> {40} [style=dashed];
34 -> {35}; 34 -> {35};
34 -> {33} [color=green style=dashed];
35 -> {36};
36 -> {37}; 36 -> {37};
37 -> {38}; 37 -> {38};
38 -> {39}; 38 -> {39};
39 -> {40};
40 -> {41}; 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 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] [R|Contract description]
< <
CallsInPlace(block, AT_LEAST_ONCE) 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|>|() 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] [R|Contract description]
< <
CallsInPlace(block, AT_LEAST_ONCE) 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|>|() R|<local>/block|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()
} }
public final fun test_1(): R|kotlin/Unit| { public final fun test_1(): R|kotlin/Unit| {
@@ -2,6 +2,7 @@
import kotlin.contracts.* import kotlin.contracts.*
@OptIn(ExperimentalContracts::class)
inline fun inlineRun(block: () -> Unit) { inline fun inlineRun(block: () -> Unit) {
contract { contract {
callsInPlace(block, InvocationKind.AT_LEAST_ONCE) callsInPlace(block, InvocationKind.AT_LEAST_ONCE)
@@ -9,6 +10,7 @@ inline fun inlineRun(block: () -> Unit) {
block() block()
} }
@OptIn(ExperimentalContracts::class)
fun myRun(block: () -> Unit) { fun myRun(block: () -> Unit) {
contract { contract {
callsInPlace(block, InvocationKind.AT_LEAST_ONCE) callsInPlace(block, InvocationKind.AT_LEAST_ONCE)
@@ -9,120 +9,134 @@ digraph atMostOnce_kt {
subgraph cluster_1 { subgraph cluster_1 {
color=blue color=blue
1 [label="Enter block"]; 1 [label="Enter block"];
2 [label="Function call: R|<local>/block|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()" style="filled" fillcolor=yellow]; subgraph cluster_2 {
3 [label="Exit block"]; 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}; 0 -> {1};
1 -> {2}; 1 -> {2};
2 -> {3}; 2 -> {3};
3 -> {4}; 3 -> {4};
4 -> {5};
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];
}
5 -> {6}; 5 -> {6};
6 -> {7};
7 -> {8};
8 -> {9};
subgraph cluster_4 { subgraph cluster_3 {
color=red color=red
10 [label="Enter function test_1" style="filled" fillcolor=red]; 15 [label="Enter function myRun" style="filled" fillcolor=red];
subgraph cluster_5 { subgraph cluster_4 {
color=blue color=blue
11 [label="Enter block"]; 16 [label="Enter block"];
12 [label="Variable declaration: lval x: R|kotlin/Int|"]; subgraph cluster_5 {
13 [label="Postponed enter to lambda"];
subgraph cluster_6 {
color=blue color=blue
20 [label="Enter function anonymousFunction" style="filled" fillcolor=red]; 17 [label="Enter block"];
subgraph cluster_7 { 18 [label="Exit block"];
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];
} }
14 [label="Postponed exit from lambda"]; 19 [label="Function call: R|<local>/block|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()" style="filled" fillcolor=yellow];
15 [label="Function call: R|/inlineRun|(...)" style="filled" fillcolor=yellow]; 20 [label="Exit block"];
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="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}; 15 -> {16};
16 -> {17}; 16 -> {17};
17 -> {18}; 17 -> {18};
18 -> {19}; 18 -> {19};
19 -> {20};
20 -> {21}; 20 -> {21};
21 -> {22};
22 -> {23};
23 -> {24};
24 -> {25};
25 -> {14};
subgraph cluster_8 { subgraph cluster_6 {
color=red color=red
26 [label="Enter function test_2" style="filled" fillcolor=red]; 30 [label="Enter function test_1" style="filled" fillcolor=red];
subgraph cluster_9 { subgraph cluster_7 {
color=blue color=blue
27 [label="Enter block"]; 31 [label="Enter block"];
28 [label="Variable declaration: lval x: R|kotlin/Int|"]; 32 [label="Variable declaration: lval x: R|kotlin/Int|"];
29 [label="Postponed enter to lambda"]; 33 [label="Postponed enter to lambda"];
subgraph cluster_10 { subgraph cluster_8 {
color=blue color=blue
36 [label="Enter function anonymousFunction" style="filled" fillcolor=red]; 40 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
subgraph cluster_11 { subgraph cluster_9 {
color=blue color=blue
37 [label="Enter block"]; 41 [label="Enter block"];
38 [label="Const: Int(1)"]; 42 [label="Const: Int(1)"];
39 [label="Assignment: R|<local>/x|"]; 43 [label="Assignment: R|<local>/x|"];
40 [label="Exit block"]; 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"]; 34 [label="Postponed exit from lambda"];
31 [label="Function call: R|/myRun|(...)" style="filled" fillcolor=yellow]; 35 [label="Function call: R|/inlineRun|(...)" style="filled" fillcolor=yellow];
32 [label="Access variable R|<local>/x|"]; 36 [label="Access variable R|<local>/x|"];
33 [label="Function call: R|<local>/x|.R|kotlin/Int.inc|()" style="filled" fillcolor=yellow]; 37 [label="Function call: R|<local>/x|.R|kotlin/Int.inc|()" style="filled" fillcolor=yellow];
34 [label="Exit block"]; 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 -> {31};
31 -> {32}; 31 -> {32};
32 -> {33}; 32 -> {33};
33 -> {34}; 33 -> {34 40 35};
33 -> {40} [style=dashed];
34 -> {35}; 34 -> {35};
35 -> {36};
36 -> {37}; 36 -> {37};
37 -> {38}; 37 -> {38};
38 -> {39}; 38 -> {39};
39 -> {40};
40 -> {41}; 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 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] [R|Contract description]
< <
CallsInPlace(block, AT_MOST_ONCE) 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|>|() 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] [R|Contract description]
< <
CallsInPlace(block, AT_MOST_ONCE) 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|>|() R|<local>/block|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()
} }
public final fun test_1(): R|kotlin/Unit| { public final fun test_1(): R|kotlin/Unit| {
@@ -2,6 +2,7 @@
import kotlin.contracts.* import kotlin.contracts.*
@OptIn(ExperimentalContracts::class)
inline fun inlineRun(block: () -> Unit) { inline fun inlineRun(block: () -> Unit) {
contract { contract {
callsInPlace(block, InvocationKind.AT_MOST_ONCE) callsInPlace(block, InvocationKind.AT_MOST_ONCE)
@@ -9,6 +10,7 @@ inline fun inlineRun(block: () -> Unit) {
block() block()
} }
@OptIn(ExperimentalContracts::class)
fun myRun(block: () -> Unit) { fun myRun(block: () -> Unit) {
contract { contract {
callsInPlace(block, InvocationKind.AT_MOST_ONCE) callsInPlace(block, InvocationKind.AT_MOST_ONCE)
@@ -9,123 +9,144 @@ digraph contractsUsage_kt {
subgraph cluster_1 { subgraph cluster_1 {
color=blue color=blue
1 [label="Enter block"]; 1 [label="Enter block"];
2 [label="Access variable R|<local>/x|"]; subgraph cluster_2 {
3 [label="Function call: R|<local>/x|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()" style="filled" fillcolor=yellow]; color=blue
4 [label="Exit block"]; 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}; 0 -> {1};
1 -> {2}; 1 -> {2};
2 -> {3}; 2 -> {3};
3 -> {4}; 3 -> {4};
4 -> {5}; 4 -> {5};
5 -> {6};
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];
}
6 -> {7}; 6 -> {7};
7 -> {8};
8 -> {9}; subgraph cluster_3 {
9 -> {10}; color=red
10 -> {11}; 16 [label="Enter function baz" style="filled" fillcolor=red];
11 -> {13 12}; subgraph cluster_4 {
12 -> {19}; color=blue
13 -> {14}; 17 [label="Enter block"];
14 -> {15}; subgraph cluster_5 {
15 -> {16}; 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}; 16 -> {17};
17 -> {18}; 17 -> {18};
18 -> {19}; 18 -> {19};
19 -> {20}; 19 -> {20};
20 -> {21}; 20 -> {21};
21 -> {22};
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];
}
22 -> {23}; 22 -> {23};
23 -> {24}; 23 -> {25 24};
24 -> {25}; 24 -> {31};
25 -> {26}; 25 -> {26};
26 -> {27}; 26 -> {27};
27 -> {29 28}; 27 -> {28};
28 -> {39}; 28 -> {29};
29 -> {30}; 29 -> {30};
30 -> {31}; 30 -> {31};
31 -> {32}; 31 -> {32};
32 -> {33}; 32 -> {33};
33 -> {34};
34 -> {35}; subgraph cluster_9 {
35 -> {43}; color=red
35 -> {36} [style=dotted]; 42 [label="Enter function foo" style="filled" fillcolor=red];
36 -> {37} [style=dotted]; subgraph cluster_10 {
37 -> {38} [style=dotted]; color=blue
38 -> {39} [style=dotted]; 43 [label="Enter block"];
39 -> {40}; subgraph cluster_11 {
40 -> {41}; color=blue
41 -> {42}; 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}; 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 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] [R|Contract description]
< <
CallsInPlace(x, EXACTLY_ONCE) 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|<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] [R|Contract description]
< <
CallsInPlace(this, AT_MOST_ONCE) 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 () { when () {
Boolean(true) -> { Boolean(true) -> {
this@R|/baz|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|() 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] [R|Contract description]
< <
CallsInPlace(x, AT_LEAST_ONCE) CallsInPlace(x, AT_LEAST_ONCE)
CallsInPlace(y, AT_MOST_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 () { when () {
Boolean(true) -> { Boolean(true) -> {
R|<local>/x|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|() R|<local>/x|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()
@@ -1,7 +1,7 @@
// !DUMP_CFG // !DUMP_CFG
import kotlin.contracts.* import kotlin.contracts.*
@ExperimentalContracts @OptIn(ExperimentalContracts::class)
fun bar(x: () -> Unit) { fun bar(x: () -> Unit) {
contract { contract {
callsInPlace(x, InvocationKind.EXACTLY_ONCE) callsInPlace(x, InvocationKind.EXACTLY_ONCE)
@@ -10,7 +10,7 @@ fun bar(x: () -> Unit) {
x.invoke() x.invoke()
} }
@ExperimentalContracts @OptIn(ExperimentalContracts::class)
fun (() -> Unit).baz() { fun (() -> Unit).baz() {
contract { contract {
callsInPlace(this@baz, InvocationKind.AT_MOST_ONCE) callsInPlace(this@baz, InvocationKind.AT_MOST_ONCE)
@@ -21,7 +21,7 @@ fun (() -> Unit).baz() {
} }
} }
@ExperimentalContracts @OptIn(ExperimentalContracts::class)
fun foo(x: () -> Unit, y: () -> Unit) { fun foo(x: () -> Unit, y: () -> Unit) {
contract { contract {
callsInPlace(x, InvocationKind.AT_LEAST_ONCE) callsInPlace(x, InvocationKind.AT_LEAST_ONCE)
@@ -9,122 +9,136 @@ digraph exactlyOnce_kt {
subgraph cluster_1 { subgraph cluster_1 {
color=blue color=blue
1 [label="Enter block"]; 1 [label="Enter block"];
2 [label="Function call: R|<local>/block|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()" style="filled" fillcolor=yellow]; subgraph cluster_2 {
3 [label="Exit block"]; 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}; 0 -> {1};
1 -> {2}; 1 -> {2};
2 -> {3}; 2 -> {3};
3 -> {4}; 3 -> {4};
4 -> {5};
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];
}
5 -> {6}; 5 -> {6};
6 -> {7};
7 -> {8};
8 -> {9};
subgraph cluster_4 { subgraph cluster_3 {
color=red color=red
10 [label="Enter function test_1" style="filled" fillcolor=red]; 15 [label="Enter function myRun" style="filled" fillcolor=red];
subgraph cluster_5 { subgraph cluster_4 {
color=blue color=blue
11 [label="Enter block"]; 16 [label="Enter block"];
12 [label="Variable declaration: lval x: R|kotlin/Int|"]; subgraph cluster_5 {
13 [label="Postponed enter to lambda"];
subgraph cluster_6 {
color=blue color=blue
20 [label="Enter function anonymousFunction" style="filled" fillcolor=red]; 17 [label="Enter block"];
subgraph cluster_7 { 18 [label="Exit block"];
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];
} }
14 [label="Postponed exit from lambda"]; 19 [label="Function call: R|<local>/block|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()" style="filled" fillcolor=yellow];
15 [label="Function call: R|/inlineRun|(...)" style="filled" fillcolor=yellow]; 20 [label="Exit block"];
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="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}; 15 -> {16};
16 -> {17}; 16 -> {17};
17 -> {18}; 17 -> {18};
18 -> {19}; 18 -> {19};
19 -> {20};
20 -> {21}; 20 -> {21};
21 -> {22};
22 -> {23};
23 -> {24};
24 -> {25};
25 -> {14};
subgraph cluster_8 { subgraph cluster_6 {
color=red color=red
26 [label="Enter function test_2" style="filled" fillcolor=red]; 30 [label="Enter function test_1" style="filled" fillcolor=red];
subgraph cluster_9 { subgraph cluster_7 {
color=blue color=blue
27 [label="Enter block"]; 31 [label="Enter block"];
28 [label="Variable declaration: lval x: R|kotlin/Int|"]; 32 [label="Variable declaration: lval x: R|kotlin/Int|"];
29 [label="Postponed enter to lambda"]; 33 [label="Postponed enter to lambda"];
subgraph cluster_10 { subgraph cluster_8 {
color=blue color=blue
36 [label="Enter function anonymousFunction" style="filled" fillcolor=red]; 40 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
subgraph cluster_11 { subgraph cluster_9 {
color=blue color=blue
37 [label="Enter block"]; 41 [label="Enter block"];
38 [label="Const: Int(1)"]; 42 [label="Const: Int(1)"];
39 [label="Assignment: R|<local>/x|"]; 43 [label="Assignment: R|<local>/x|"];
40 [label="Exit block"]; 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"]; 34 [label="Postponed exit from lambda"];
31 [label="Function call: R|/myRun|(...)" style="filled" fillcolor=yellow]; 35 [label="Function call: R|/inlineRun|(...)" style="filled" fillcolor=yellow];
32 [label="Access variable R|<local>/x|"]; 36 [label="Access variable R|<local>/x|"];
33 [label="Function call: R|<local>/x|.R|kotlin/Int.inc|()" style="filled" fillcolor=yellow]; 37 [label="Function call: R|<local>/x|.R|kotlin/Int.inc|()" style="filled" fillcolor=yellow];
34 [label="Exit block"]; 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 -> {31};
31 -> {32}; 31 -> {32};
32 -> {33}; 32 -> {33};
33 -> {34}; 33 -> {40 35};
33 -> {34} [style=dotted];
33 -> {40} [style=dashed];
34 -> {35}; 34 -> {35};
35 -> {36};
36 -> {37}; 36 -> {37};
37 -> {38}; 37 -> {38};
38 -> {39}; 38 -> {39};
39 -> {40};
40 -> {41}; 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 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] [R|Contract description]
< <
CallsInPlace(block, EXACTLY_ONCE) 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|>|() 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] [R|Contract description]
< <
CallsInPlace(block, EXACTLY_ONCE) 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|>|() R|<local>/block|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()
} }
public final fun test_1(): R|kotlin/Unit| { public final fun test_1(): R|kotlin/Unit| {
@@ -2,6 +2,7 @@
import kotlin.contracts.* import kotlin.contracts.*
@OptIn(ExperimentalContracts::class)
inline fun inlineRun(block: () -> Unit) { inline fun inlineRun(block: () -> Unit) {
contract { contract {
callsInPlace(block, InvocationKind.EXACTLY_ONCE) callsInPlace(block, InvocationKind.EXACTLY_ONCE)
@@ -9,6 +10,7 @@ inline fun inlineRun(block: () -> Unit) {
block() block()
} }
@OptIn(ExperimentalContracts::class)
fun myRun(block: () -> Unit) { fun myRun(block: () -> Unit) {
contract { contract {
callsInPlace(block, InvocationKind.EXACTLY_ONCE) callsInPlace(block, InvocationKind.EXACTLY_ONCE)
@@ -11,221 +11,222 @@ digraph flow_kt {
1 [label="Enter block"]; 1 [label="Enter block"];
subgraph cluster_2 { subgraph cluster_2 {
color=blue color=blue
2 [label="Enter when"]; 2 [label="Enter block"];
subgraph cluster_3 { 3 [label="Exit block"];
color=blue }
3 [label="Enter when branch condition "]; subgraph cluster_3 {
4 [label="Const: Boolean(true)"]; color=blue
5 [label="Exit when branch condition"]; 4 [label="Enter when"];
}
6 [label="Synthetic else branch"];
7 [label="Enter when branch result"];
subgraph cluster_4 { subgraph cluster_4 {
color=blue color=blue
8 [label="Enter block"]; 5 [label="Enter when branch condition "];
9 [label="Access variable R|<local>/x|"]; 6 [label="Const: Boolean(true)"];
10 [label="Function call: R|<local>/x|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()" style="filled" fillcolor=yellow]; 7 [label="Exit when branch condition"];
11 [label="Jump: ^bar Unit"];
12 [label="Stub" style="filled" fillcolor=gray];
13 [label="Exit block" style="filled" fillcolor=gray];
} }
14 [label="Exit when branch result" style="filled" fillcolor=gray]; 8 [label="Synthetic else branch"];
15 [label="Exit when"]; 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|"]; 18 [label="Access variable R|<local>/x|"];
17 [label="Function call: R|/bar|(...)" style="filled" fillcolor=yellow]; 19 [label="Function call: R|/bar|(...)" style="filled" fillcolor=yellow];
18 [label="Exit block"]; 20 [label="Exit block"];
} }
19 [label="Exit function bar" style="filled" fillcolor=red]; 21 [label="Exit function bar" style="filled" fillcolor=red];
} }
0 -> {1}; 0 -> {1};
1 -> {2}; 1 -> {2};
2 -> {3}; 2 -> {3};
3 -> {4}; 3 -> {4};
4 -> {5}; 4 -> {5};
5 -> {7 6}; 5 -> {6};
6 -> {15}; 6 -> {7};
7 -> {8}; 7 -> {9 8};
8 -> {9}; 8 -> {17};
9 -> {10}; 9 -> {10};
10 -> {11}; 10 -> {11};
11 -> {19}; 11 -> {12};
11 -> {12} [style=dotted]; 12 -> {13};
12 -> {13} [style=dotted]; 13 -> {21};
13 -> {14} [style=dotted]; 13 -> {14} [style=dotted];
14 -> {15} [style=dotted]; 14 -> {15} [style=dotted];
15 -> {16}; 15 -> {16} [style=dotted];
16 -> {17}; 16 -> {17} [style=dotted];
17 -> {18}; 17 -> {18};
18 -> {19}; 18 -> {19};
19 -> {20};
20 -> {21};
subgraph cluster_5 { subgraph cluster_6 {
color=red color=red
20 [label="Enter function foo" style="filled" fillcolor=red]; 30 [label="Enter function foo" style="filled" fillcolor=red];
subgraph cluster_6 { subgraph cluster_7 {
color=blue color=blue
21 [label="Enter block"]; 31 [label="Enter block"];
subgraph cluster_7 { subgraph cluster_8 {
color=blue color=blue
22 [label="Enter when"]; 32 [label="Enter block"];
subgraph cluster_8 { 33 [label="Exit block"];
color=blue }
23 [label="Enter when branch condition "]; subgraph cluster_9 {
24 [label="Const: Boolean(true)"]; color=blue
25 [label="Exit when branch condition"]; 34 [label="Enter when"];
}
subgraph cluster_9 {
color=blue
26 [label="Enter when branch condition else"];
27 [label="Exit when branch condition"];
}
28 [label="Enter when branch result"];
subgraph cluster_10 { subgraph cluster_10 {
color=blue color=blue
29 [label="Enter block"]; 35 [label="Enter when branch condition "];
subgraph cluster_11 { 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 color=blue
30 [label="Enter when"]; 42 [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"];
subgraph cluster_14 { subgraph cluster_14 {
color=blue color=blue
37 [label="Enter block"]; 43 [label="Enter when branch condition "];
38 [label="Access variable R|<local>/y|"]; 44 [label="Const: Boolean(false)"];
39 [label="Function call: R|<local>/y|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()" style="filled" fillcolor=yellow]; 45 [label="Exit when branch condition"];
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];
} }
45 [label="Exit when branch result" style="filled" fillcolor=gray];
46 [label="Enter when branch result"];
subgraph cluster_15 { subgraph cluster_15 {
color=blue color=blue
47 [label="Enter block"]; 46 [label="Enter when branch condition else"];
48 [label="Access variable R|<local>/y|"]; 47 [label="Exit when branch condition"];
49 [label="Function call: R|<local>/y|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()" style="filled" fillcolor=yellow];
50 [label="Exit block"];
} }
51 [label="Exit when branch result"]; 48 [label="Enter when branch result"];
52 [label="Exit when"]; subgraph cluster_16 {
}
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 {
color=blue color=blue
63 [label="Enter while loop"]; 49 [label="Enter block"];
subgraph cluster_19 { 50 [label="Access variable R|<local>/y|"];
color=blue 51 [label="Function call: R|<local>/y|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()" style="filled" fillcolor=yellow];
64 [label="Enter loop condition"]; 52 [label="Access variable R|<local>/z|"];
65 [label="Access variable R|<local>/<iterator>|"]; 53 [label="Function call: R|<local>/z|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()" style="filled" fillcolor=yellow];
66 [label="Function call: R|<local>/<iterator>|.R|SubstitutionOverride<kotlin/collections/IntIterator.hasNext: R|kotlin/Boolean|>|()" style="filled" fillcolor=yellow]; 54 [label="Jump: ^foo Unit"];
67 [label="Exit loop condition"]; 55 [label="Stub" style="filled" fillcolor=gray];
} 56 [label="Exit block" style="filled" fillcolor=gray];
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"];
} }
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|"]; 65 [label="Exit block"];
80 [label="Function call: R|<local>/y|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()" style="filled" fillcolor=yellow];
81 [label="Exit block"];
} }
82 [label="Exit when branch result"]; 66 [label="Exit when branch result"];
83 [label="Exit when"]; 67 [label="Enter when branch result"];
} subgraph cluster_18 {
subgraph cluster_22 {
color=blue
84 [label="Enter do-while loop"];
subgraph cluster_23 {
color=blue color=blue
85 [label="Enter loop block"]; 68 [label="Enter block"];
subgraph cluster_24 { subgraph cluster_19 {
color=blue color=blue
86 [label="Enter block"]; 69 [label="Enter block"];
87 [label="Access variable R|<local>/z|"]; 70 [label="Const: Int(0)"];
88 [label="Function call: R|/bar|(...)" style="filled" fillcolor=yellow]; 71 [label="Const: Int(0)"];
89 [label="Exit block"]; 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 { subgraph cluster_25 {
color=blue color=blue
91 [label="Enter loop condition"]; 97 [label="Enter loop block"];
92 [label="Const: Boolean(true)"]; subgraph cluster_26 {
93 [label="Exit loop condition"]; 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}; 30 -> {31};
31 -> {32}; 31 -> {32};
32 -> {33}; 32 -> {33};
33 -> {46 34}; 33 -> {34};
34 -> {35}; 34 -> {35};
35 -> {36}; 35 -> {36};
36 -> {37}; 36 -> {37};
37 -> {38}; 37 -> {67 38};
38 -> {39}; 38 -> {39};
39 -> {40}; 39 -> {40};
40 -> {41}; 40 -> {41};
41 -> {42}; 41 -> {42};
42 -> {96}; 42 -> {43};
42 -> {43} [style=dotted]; 43 -> {44};
43 -> {44} [style=dotted]; 44 -> {45};
44 -> {45} [style=dotted]; 45 -> {58 46};
45 -> {52} [style=dotted];
46 -> {47}; 46 -> {47};
47 -> {48}; 47 -> {48};
48 -> {49}; 48 -> {49};
@@ -234,10 +235,11 @@ digraph flow_kt {
51 -> {52}; 51 -> {52};
52 -> {53}; 52 -> {53};
53 -> {54}; 53 -> {54};
54 -> {83}; 54 -> {108};
55 -> {56}; 54 -> {55} [style=dotted];
56 -> {57}; 55 -> {56} [style=dotted];
57 -> {58}; 56 -> {57} [style=dotted];
57 -> {64} [style=dotted];
58 -> {59}; 58 -> {59};
59 -> {60}; 59 -> {60};
60 -> {61}; 60 -> {61};
@@ -246,8 +248,8 @@ digraph flow_kt {
63 -> {64}; 63 -> {64};
64 -> {65}; 64 -> {65};
65 -> {66}; 65 -> {66};
66 -> {67}; 66 -> {95};
67 -> {77 68}; 67 -> {68};
68 -> {69}; 68 -> {69};
69 -> {70}; 69 -> {70};
70 -> {71}; 70 -> {71};
@@ -256,10 +258,10 @@ digraph flow_kt {
73 -> {74}; 73 -> {74};
74 -> {75}; 74 -> {75};
75 -> {76}; 75 -> {76};
76 -> {64} [color=green style=dashed]; 76 -> {77};
77 -> {78}; 77 -> {78};
78 -> {79}; 78 -> {79};
79 -> {80}; 79 -> {89 80};
80 -> {81}; 80 -> {81};
81 -> {82}; 81 -> {82};
82 -> {83}; 82 -> {83};
@@ -268,14 +270,26 @@ digraph flow_kt {
85 -> {86}; 85 -> {86};
86 -> {87}; 86 -> {87};
87 -> {88}; 87 -> {88};
88 -> {89}; 88 -> {76} [color=green style=dashed];
89 -> {90}; 89 -> {90};
90 -> {91}; 90 -> {91};
91 -> {92}; 91 -> {92};
92 -> {93}; 92 -> {93};
93 -> {94} [style=dotted]; 93 -> {94};
93 -> {85} [color=green style=dashed]; 94 -> {95};
94 -> {95} [style=dotted]; 95 -> {96};
95 -> {96} [style=dotted]; 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 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] [R|Contract description]
< <
CallsInPlace(x, EXACTLY_ONCE) 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 () { when () {
Boolean(true) -> { Boolean(true) -> {
R|<local>/x|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|() R|<local>/x|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()
@@ -15,7 +21,7 @@ FILE: flow.kt
R|/bar|(R|<local>/x|) 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] [R|Contract description]
< <
CallsInPlace(x, UNKNOWN) CallsInPlace(x, UNKNOWN)
@@ -23,7 +29,15 @@ FILE: flow.kt
CallsInPlace(z, AT_LEAST_ONCE) 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 () { when () {
Boolean(true) -> { Boolean(true) -> {
{ {
@@ -1,7 +1,7 @@
// !DUMP_CFG // !DUMP_CFG
import kotlin.contracts.* import kotlin.contracts.*
@ExperimentalContracts @OptIn(ExperimentalContracts::class)
fun bar(x: () -> Unit) { fun bar(x: () -> Unit) {
contract { contract {
callsInPlace(x, InvocationKind.EXACTLY_ONCE) callsInPlace(x, InvocationKind.EXACTLY_ONCE)
@@ -15,7 +15,7 @@ fun bar(x: () -> Unit) {
bar(x) bar(x)
} }
@ExperimentalContracts @OptIn(ExperimentalContracts::class)
fun foo(x: () -> Unit, y: () -> Unit, z: () -> Unit) { fun foo(x: () -> Unit, y: () -> Unit, z: () -> Unit) {
contract { contract {
callsInPlace(x, InvocationKind.UNKNOWN) callsInPlace(x, InvocationKind.UNKNOWN)
@@ -11,80 +11,94 @@ digraph inPlaceLambda_kt {
1 [label="Enter block"]; 1 [label="Enter block"];
subgraph cluster_2 { subgraph cluster_2 {
color=blue color=blue
2 [label="Enter when"]; 2 [label="Enter block"];
subgraph cluster_3 { 3 [label="Exit block"];
color=blue }
3 [label="Enter when branch condition "]; subgraph cluster_3 {
4 [label="Const: Boolean(true)"]; color=blue
5 [label="Exit when branch condition"]; 4 [label="Enter when"];
}
6 [label="Synthetic else branch"];
7 [label="Enter when branch result"];
subgraph cluster_4 { subgraph cluster_4 {
color=blue color=blue
8 [label="Enter block"]; 5 [label="Enter when branch condition "];
9 [label="Function call: R|<local>/x|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()" style="filled" fillcolor=yellow]; 6 [label="Const: Boolean(true)"];
10 [label="Exit block"]; 7 [label="Exit when branch condition"];
} }
11 [label="Exit when branch result"]; 8 [label="Synthetic else branch"];
12 [label="Exit when"]; 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}; 0 -> {1};
1 -> {2}; 1 -> {2};
2 -> {3}; 2 -> {3};
3 -> {4}; 3 -> {4};
4 -> {5}; 4 -> {5};
5 -> {7 6}; 5 -> {6};
6 -> {12}; 6 -> {7};
7 -> {8}; 7 -> {9 8};
8 -> {9}; 8 -> {14};
9 -> {10}; 9 -> {10};
10 -> {11}; 10 -> {11};
11 -> {12}; 11 -> {12};
12 -> {13}; 12 -> {13};
13 -> {14}; 13 -> {14};
14 -> {15};
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];
}
15 -> {16}; 15 -> {16};
16 -> {17};
17 -> {18}; subgraph cluster_6 {
18 -> {19 23 20}; color=red
18 -> {23} [style=dashed]; 25 [label="Enter function foo" style="filled" fillcolor=red];
19 -> {20}; subgraph cluster_7 {
20 -> {21}; color=blue
21 -> {22}; 26 [label="Enter block"];
23 -> {24}; subgraph cluster_8 {
24 -> {25}; 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}; 25 -> {26};
26 -> {27}; 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 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] [R|Contract description]
< <
CallsInPlace(x, AT_MOST_ONCE) 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 () { when () {
Boolean(true) -> { Boolean(true) -> {
R|<local>/x|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|() 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] [R|Contract description]
< <
CallsInPlace(x, AT_LEAST_ONCE) 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|<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|/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|>|() R|<local>/x|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()
@@ -1,7 +1,7 @@
// !DUMP_CFG // !DUMP_CFG
import kotlin.contracts.* import kotlin.contracts.*
@ExperimentalContracts @OptIn(ExperimentalContracts::class)
fun bar(x: () -> Unit) { fun bar(x: () -> Unit) {
contract { contract {
callsInPlace(x, InvocationKind.AT_MOST_ONCE) callsInPlace(x, InvocationKind.AT_MOST_ONCE)
@@ -12,7 +12,7 @@ fun bar(x: () -> Unit) {
} }
} }
@ExperimentalContracts @OptIn(ExperimentalContracts::class)
fun foo(x: () -> Unit) { fun foo(x: () -> Unit) {
contract { contract {
callsInPlace(x, InvocationKind.AT_LEAST_ONCE) callsInPlace(x, InvocationKind.AT_LEAST_ONCE)
@@ -9,62 +9,64 @@ digraph simple_kt {
subgraph cluster_1 { subgraph cluster_1 {
color=blue color=blue
1 [label="Enter block"]; 1 [label="Enter block"];
2 [label="Access variable R|<local>/x|"]; subgraph cluster_2 {
3 [label="Function call: R|<local>/x|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()" style="filled" fillcolor=yellow]; color=blue
4 [label="Exit block"]; 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}; 0 -> {1};
1 -> {2}; 1 -> {2};
2 -> {3}; 2 -> {3};
3 -> {4}; 3 -> {4};
4 -> {5}; 4 -> {5};
5 -> {6};
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];
}
6 -> {7}; 6 -> {7};
7 -> {8};
8 -> {9}; subgraph cluster_3 {
9 -> {10}; color=red
10 -> {11}; 16 [label="Enter function foo" style="filled" fillcolor=red];
11 -> {12}; subgraph cluster_4 {
12 -> {13}; color=blue
13 -> {15 14}; 17 [label="Enter block"];
14 -> {20}; subgraph cluster_5 {
15 -> {16}; 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}; 16 -> {17};
17 -> {18}; 17 -> {18};
18 -> {19}; 18 -> {19};
@@ -73,5 +75,17 @@ digraph simple_kt {
21 -> {22}; 21 -> {22};
22 -> {23}; 22 -> {23};
23 -> {24}; 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 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] [R|Contract description]
< <
CallsInPlace(x, EXACTLY_ONCE) 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|<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] [R|Contract description]
< <
CallsInPlace(x, EXACTLY_ONCE) CallsInPlace(x, EXACTLY_ONCE)
@@ -16,7 +22,15 @@ FILE: simple.kt
CallsInPlace(z, EXACTLY_ONCE) 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|>|() R|<local>/x|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()
when () { when () {
Boolean(true) -> { Boolean(true) -> {
@@ -1,7 +1,7 @@
// !DUMP_CFG // !DUMP_CFG
import kotlin.contracts.* import kotlin.contracts.*
@ExperimentalContracts @OptIn(ExperimentalContracts::class)
fun bar(x: () -> Unit) { fun bar(x: () -> Unit) {
contract { contract {
callsInPlace(x, InvocationKind.EXACTLY_ONCE) callsInPlace(x, InvocationKind.EXACTLY_ONCE)
@@ -10,7 +10,7 @@ fun bar(x: () -> Unit) {
x.invoke() x.invoke()
} }
@ExperimentalContracts @OptIn(ExperimentalContracts::class)
fun foo(x: () -> Unit, y: () -> Unit, z: () -> Unit) { fun foo(x: () -> Unit, y: () -> Unit, z: () -> Unit) {
contract { contract {
callsInPlace(x, InvocationKind.EXACTLY_ONCE) callsInPlace(x, InvocationKind.EXACTLY_ONCE)
@@ -9,122 +9,136 @@ digraph unknown_kt {
subgraph cluster_1 { subgraph cluster_1 {
color=blue color=blue
1 [label="Enter block"]; 1 [label="Enter block"];
2 [label="Function call: R|<local>/block|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()" style="filled" fillcolor=yellow]; subgraph cluster_2 {
3 [label="Exit block"]; 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}; 0 -> {1};
1 -> {2}; 1 -> {2};
2 -> {3}; 2 -> {3};
3 -> {4}; 3 -> {4};
4 -> {5};
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];
}
5 -> {6}; 5 -> {6};
6 -> {7};
7 -> {8};
8 -> {9};
subgraph cluster_4 { subgraph cluster_3 {
color=red color=red
10 [label="Enter function test_1" style="filled" fillcolor=red]; 15 [label="Enter function myRun" style="filled" fillcolor=red];
subgraph cluster_5 { subgraph cluster_4 {
color=blue color=blue
11 [label="Enter block"]; 16 [label="Enter block"];
12 [label="Variable declaration: lval x: R|kotlin/Int|"]; subgraph cluster_5 {
13 [label="Postponed enter to lambda"];
subgraph cluster_6 {
color=blue color=blue
20 [label="Enter function anonymousFunction" style="filled" fillcolor=red]; 17 [label="Enter block"];
subgraph cluster_7 { 18 [label="Exit block"];
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];
} }
14 [label="Postponed exit from lambda"]; 19 [label="Function call: R|<local>/block|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()" style="filled" fillcolor=yellow];
15 [label="Function call: R|/inlineRun|(...)" style="filled" fillcolor=yellow]; 20 [label="Exit block"];
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="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}; 15 -> {16};
16 -> {17}; 16 -> {17};
17 -> {18}; 17 -> {18};
18 -> {19}; 18 -> {19};
19 -> {20};
20 -> {21}; 20 -> {21};
21 -> {22};
22 -> {23};
23 -> {24};
24 -> {25};
25 -> {14};
subgraph cluster_8 { subgraph cluster_6 {
color=red color=red
26 [label="Enter function test_2" style="filled" fillcolor=red]; 30 [label="Enter function test_1" style="filled" fillcolor=red];
subgraph cluster_9 { subgraph cluster_7 {
color=blue color=blue
27 [label="Enter block"]; 31 [label="Enter block"];
28 [label="Variable declaration: lval x: R|kotlin/Int|"]; 32 [label="Variable declaration: lval x: R|kotlin/Int|"];
29 [label="Postponed enter to lambda"]; 33 [label="Postponed enter to lambda"];
subgraph cluster_10 { subgraph cluster_8 {
color=blue color=blue
36 [label="Enter function anonymousFunction" style="filled" fillcolor=red]; 40 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
subgraph cluster_11 { subgraph cluster_9 {
color=blue color=blue
37 [label="Enter block"]; 41 [label="Enter block"];
38 [label="Const: Int(1)"]; 42 [label="Const: Int(1)"];
39 [label="Assignment: R|<local>/x|"]; 43 [label="Assignment: R|<local>/x|"];
40 [label="Exit block"]; 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"]; 34 [label="Postponed exit from lambda"];
31 [label="Function call: R|/myRun|(...)" style="filled" fillcolor=yellow]; 35 [label="Function call: R|/inlineRun|(...)" style="filled" fillcolor=yellow];
32 [label="Access variable R|<local>/x|"]; 36 [label="Access variable R|<local>/x|"];
33 [label="Function call: R|<local>/x|.R|kotlin/Int.inc|()" style="filled" fillcolor=yellow]; 37 [label="Function call: R|<local>/x|.R|kotlin/Int.inc|()" style="filled" fillcolor=yellow];
34 [label="Exit block"]; 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 -> {31};
30 -> {29} [color=green style=dashed];
31 -> {32}; 31 -> {32};
32 -> {33}; 32 -> {33};
33 -> {34}; 33 -> {34 40 35};
33 -> {40} [style=dashed];
34 -> {35}; 34 -> {35};
34 -> {33} [color=green style=dashed];
35 -> {36};
36 -> {37}; 36 -> {37};
37 -> {38}; 37 -> {38};
38 -> {39}; 38 -> {39};
39 -> {40};
40 -> {41}; 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 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] [R|Contract description]
< <
CallsInPlace(block, UNKNOWN) 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|>|() 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] [R|Contract description]
< <
CallsInPlace(block, UNKNOWN) 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|>|() R|<local>/block|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()
} }
public final fun test_1(): R|kotlin/Unit| { public final fun test_1(): R|kotlin/Unit| {
@@ -2,6 +2,7 @@
import kotlin.contracts.* import kotlin.contracts.*
@OptIn(ExperimentalContracts::class)
inline fun inlineRun(block: () -> Unit) { inline fun inlineRun(block: () -> Unit) {
contract { contract {
callsInPlace(block, InvocationKind.UNKNOWN) callsInPlace(block, InvocationKind.UNKNOWN)
@@ -9,6 +10,7 @@ inline fun inlineRun(block: () -> Unit) {
block() block()
} }
@OptIn(ExperimentalContracts::class)
fun myRun(block: () -> Unit) { fun myRun(block: () -> Unit) {
contract { contract {
callsInPlace(block, InvocationKind.UNKNOWN) callsInPlace(block, InvocationKind.UNKNOWN)
@@ -1,11 +1,17 @@
FILE: booleanOperators.kt 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] [R|Contract description]
< <
Returns(WILDCARD) -> b 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 () { when () {
R|<local>/b|.R|kotlin/Boolean.not|() -> { R|<local>/b|.R|kotlin/Boolean.not|() -> {
throw R|java/lang/IllegalStateException.IllegalStateException|() 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] [R|Contract description]
< <
Returns(WILDCARD) -> b1 && b2 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 () { when () {
R|<local>/b1| && R|<local>/b2|.R|kotlin/Boolean.not|() -> { R|<local>/b1| && R|<local>/b2|.R|kotlin/Boolean.not|() -> {
throw R|java/lang/IllegalStateException.IllegalStateException|() 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] [R|Contract description]
< <
Returns(WILDCARD) -> b1 || b2 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 () { when () {
R|<local>/b1| || R|<local>/b2|.R|kotlin/Boolean.not|() -> { R|<local>/b1| || R|<local>/b2|.R|kotlin/Boolean.not|() -> {
throw R|java/lang/IllegalStateException.IllegalStateException|() 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] [R|Contract description]
< <
Returns(WILDCARD) -> !b 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 () { when () {
R|<local>/b| -> { R|<local>/b| -> {
throw R|java/lang/IllegalStateException.IllegalStateException|() throw R|java/lang/IllegalStateException.IllegalStateException|()
@@ -1,5 +1,6 @@
import kotlin.contracts.* import kotlin.contracts.*
@OptIn(ExperimentalContracts::class)
fun myRequire(b: Boolean) { fun myRequire(b: Boolean) {
contract { contract {
returns() implies (b) returns() implies (b)
@@ -7,6 +8,7 @@ fun myRequire(b: Boolean) {
if (!b) throw IllegalStateException() if (!b) throw IllegalStateException()
} }
@OptIn(ExperimentalContracts::class)
fun myRequireAnd(b1: Boolean, b2: Boolean) { fun myRequireAnd(b1: Boolean, b2: Boolean) {
contract { contract {
returns() implies (b1 && b2) returns() implies (b1 && b2)
@@ -14,6 +16,7 @@ fun myRequireAnd(b1: Boolean, b2: Boolean) {
if (!(b1 && b2)) throw IllegalStateException() if (!(b1 && b2)) throw IllegalStateException()
} }
@OptIn(ExperimentalContracts::class)
fun myRequireOr(b1: Boolean, b2: Boolean) { fun myRequireOr(b1: Boolean, b2: Boolean) {
contract { contract {
returns() implies (b1 || b2) returns() implies (b1 || b2)
@@ -21,6 +24,7 @@ fun myRequireOr(b1: Boolean, b2: Boolean) {
if (!(b1 || b2)) throw IllegalStateException() if (!(b1 || b2)) throw IllegalStateException()
} }
@OptIn(ExperimentalContracts::class)
fun myRequireNot(b: Boolean) { fun myRequireNot(b: Boolean) {
contract { contract {
returns() implies (!b) returns() implies (!b)
@@ -5,25 +5,43 @@ FILE: conditionLogic.kt
Returns(NOT_NULL) -> !x == null 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| ^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|kotlin/OptIn|(markerClass = vararg(<getClass>(Q|kotlin/contracts/ExperimentalContracts|))) public final fun test2(x: R|kotlin/String?|): R|kotlin/Any?|
[R|Contract description] [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| ^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|kotlin/OptIn|(markerClass = vararg(<getClass>(Q|kotlin/contracts/ExperimentalContracts|))) public final fun test3(x: R|kotlin/String?|): R|kotlin/Any?|
[R|Contract description] [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| ^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?| @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 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)) ^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?| @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 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)) ^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?| @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 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|) ^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?| @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 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|) ^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?| @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 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|) ^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?| @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 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 () { when () {
(R|<local>/x| is R|kotlin/String|) -> { (R|<local>/x| is R|kotlin/String|) -> {
^test9 Boolean(true) ^test9 Boolean(true)
@@ -92,7 +146,13 @@ FILE: conditionLogic.kt
Returns(TRUE) -> x is kotlin/Comparable<*> || x is kotlin/CharSequence 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|) ^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?| @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 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|) ^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?| @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 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|) ^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?| @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) 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|) ^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) @OptIn(ExperimentalContracts::class)
fun test2(x: String?): Any? { fun test2(x: String?): Any? {
contract { contract {
returnsNotNull() implies (x is String && x != null) returnsNotNull() implies (x is String)
} }
return x return x
@@ -22,7 +22,7 @@ fun test2(x: String?): Any? {
@OptIn(ExperimentalContracts::class) @OptIn(ExperimentalContracts::class)
fun test3(x: String?): Any? { fun test3(x: String?): Any? {
contract { contract {
returnsNotNull() implies (x is String? || x is Any?) returnsNotNull() implies (x !is String)
} }
return x return x
@@ -1,21 +1,34 @@
FILE: eqNotEq.kt 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] [R|Contract description]
< <
Returns(TRUE) -> x != null Returns(TRUE) -> x != null
Returns(FALSE) -> 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)) ^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] [R|Contract description]
< <
Returns(WILDCARD) -> !x == null 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 () { when () {
==(R|<local>/x|, Null(null)) -> { ==(R|<local>/x|, Null(null)) -> {
throw R|java/lang/IllegalStateException.IllegalStateException|() throw R|java/lang/IllegalStateException.IllegalStateException|()
@@ -1,5 +1,6 @@
import kotlin.contracts.* import kotlin.contracts.*
@OptIn(ExperimentalContracts::class)
fun checkNotNull(x: Any?): Boolean { fun checkNotNull(x: Any?): Boolean {
contract { contract {
returns(true) implies (x != null) returns(true) implies (x != null)
@@ -8,6 +9,7 @@ fun checkNotNull(x: Any?): Boolean {
return x != null return x != null
} }
@OptIn(ExperimentalContracts::class)
fun trickyRequireNotNull(x: Any?) { fun trickyRequireNotNull(x: Any?) {
contract { contract {
returns() implies (!(x == null)) returns() implies (!(x == null))
@@ -5,7 +5,13 @@ FILE: inapplicable.kt
Returns(FALSE) -> 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(false)).R|kotlin/contracts/SimpleEffect.implies|(!=(R|<local>/x|, Null(null)))
}
)
}
^wrongFalse Boolean(true) ^wrongFalse Boolean(true)
} }
@R|kotlin/OptIn|(markerClass = vararg(<getClass>(Q|kotlin/contracts/ExperimentalContracts|))) public final fun wrongTrue(x: R|kotlin/String?|): R|kotlin/Boolean| @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 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) ^wrongTrue Boolean(false)
} }
@R|kotlin/OptIn|(markerClass = vararg(<getClass>(Q|kotlin/contracts/ExperimentalContracts|))) public final fun nullableConstant(x: R|kotlin/String?|): R|kotlin/Any?| @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 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) ^nullableConstant Int(1)
} }
public final fun string(): R|kotlin/String| { public final fun string(): R|kotlin/String| {
@@ -35,7 +53,13 @@ FILE: inapplicable.kt
Returns(NULL) -> x != null 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|() ^nullableReturn R|/string|()
} }
@R|kotlin/OptIn|(markerClass = vararg(<getClass>(Q|kotlin/contracts/ExperimentalContracts|))) public final fun returnsNull(x: R|kotlin/String?|): R|kotlin/Any?| @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 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) ^returnsNull Null(null)
} }
@R|kotlin/OptIn|(markerClass = vararg(<getClass>(Q|kotlin/contracts/ExperimentalContracts|))) public final fun wrongReturnType(x: R|kotlin/String?|): R|kotlin/Any?| @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 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) ^wrongReturnType String(true)
} }
@@ -1,11 +1,17 @@
FILE: namedArguments.kt 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] [R|Contract description]
< <
Returns(WILDCARD) -> x is kotlin/Int && y is kotlin/String 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 () { when () {
(R|<local>/x| !is R|kotlin/Int|) || (R|<local>/y| !is R|kotlin/String|) -> { (R|<local>/x| !is R|kotlin/Int|) || (R|<local>/y| !is R|kotlin/String|) -> {
throw R|java/lang/IllegalStateException.IllegalStateException|() throw R|java/lang/IllegalStateException.IllegalStateException|()
@@ -1,5 +1,6 @@
import kotlin.contracts.* import kotlin.contracts.*
@OptIn(ExperimentalContracts::class)
fun foo(x: Any, y: Any) { fun foo(x: Any, y: Any) {
contract { contract {
returns() implies (x is Int && y is String) returns() implies (x is Int && y is String)
@@ -5,7 +5,13 @@ FILE: notNull.kt
Returns(FALSE) -> 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(false)).R|kotlin/contracts/SimpleEffect.implies|(!=(R|<local>/x|, Null(null)))
}
)
}
^test1 ==(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| @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 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)) ^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?| @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 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 () { when () {
!=(R|<local>/x|, Null(null)) -> { !=(R|<local>/x|, Null(null)) -> {
^test3 Boolean(true) ^test3 Boolean(true)
@@ -38,7 +56,13 @@ FILE: notNull.kt
Returns(TRUE) -> x != null 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| lval y: R|kotlin/String?| = R|<local>/x|
when () { when () {
!=(R|<local>/y|, Null(null)) -> { !=(R|<local>/y|, Null(null)) -> {
@@ -54,6 +78,12 @@ FILE: notNull.kt
Returns(TRUE) -> x != null 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|) ^test5 R|/test2|(R|<local>/x|)
} }
@@ -3,14 +3,20 @@ FILE: propertyAccessors.kt
public abstract fun foo(): R|kotlin/Unit| 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| public get(): R|kotlin/Boolean|
[R|Contract description] [R|Contract description]
< <
Returns(TRUE) -> this != null 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)) ^ !=(this@R|/isNotNull|, Null(null))
} }
public set(value: R|kotlin/Boolean|): R|kotlin/Unit| public set(value: R|kotlin/Boolean|): R|kotlin/Unit|
@@ -19,7 +25,14 @@ FILE: propertyAccessors.kt
Returns(WILDCARD) -> this != null 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| { public final fun test_1(a: R|A?|): R|kotlin/Unit| {
when () { when () {
@@ -4,6 +4,7 @@ interface A {
fun foo() fun foo()
} }
@OptIn(ExperimentalContracts::class)
var Any?.isNotNull: Boolean var Any?.isNotNull: Boolean
get() { get() {
contract { contract {
@@ -3,13 +3,19 @@ FILE: receivers.kt
} }
public final fun R|A|.foo(): R|kotlin/Unit| { 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] [R|Contract description]
< <
Returns(WILDCARD) -> this != null 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 () { when () {
==(this@R|/myRequireNotNull|, Null(null)) -> { ==(this@R|/myRequireNotNull|, Null(null)) -> {
throw R|java/lang/IllegalStateException.IllegalStateException|() throw R|java/lang/IllegalStateException.IllegalStateException|()
@@ -4,6 +4,7 @@ interface A
fun A.foo() {} fun A.foo() {}
@OptIn(ExperimentalContracts::class)
fun Any?.myRequireNotNull() { fun Any?.myRequireNotNull() {
contract { contract {
returns() implies (this@myRequireNotNull != null) returns() implies (this@myRequireNotNull != null)
@@ -5,7 +5,13 @@ FILE: safeCall.kt
Returns(NOT_NULL) -> x != null 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| } ^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?| @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 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| } ^test2 R|<local>/x|?.{ $subj$.R|kotlin/String.length| }
} }
@@ -5,7 +5,13 @@ FILE: trickyCases.kt
Returns(NOT_NULL) -> x != null 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| ^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|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 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 () { ^test2 when () {
!=(R|<local>/x|, Null(null)) -> { !=(R|<local>/x|, Null(null)) -> {
Boolean(true) Boolean(true)
@@ -31,7 +43,13 @@ FILE: trickyCases.kt
Returns(NOT_NULL) -> x != null 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 () { ^test3 when () {
Boolean(true) -> { Boolean(true) -> {
R|<local>/x| R|<local>/x|
@@ -48,7 +66,13 @@ FILE: trickyCases.kt
Returns(NOT_NULL) -> x != null 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 () { ^test4 when () {
!=(R|<local>/x|, Null(null)) -> { !=(R|<local>/x|, Null(null)) -> {
when () { when () {
@@ -1,12 +1,19 @@
FILE: typePredicate.kt 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] [R|Contract description]
< <
Returns(TRUE) -> x is kotlin/String Returns(TRUE) -> x is kotlin/String
Returns(FALSE) -> 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|) ^checkIsString (R|<local>/x| is R|kotlin/String|)
} }
public final fun test(x: R|kotlin/Any|): R|kotlin/Unit| { public final fun test(x: R|kotlin/Any|): R|kotlin/Unit| {
@@ -1,5 +1,6 @@
import kotlin.contracts.* import kotlin.contracts.*
@OptIn(ExperimentalContracts::class)
fun checkIsString(x: Any): Boolean { fun checkIsString(x: Any): Boolean {
contract { contract {
returns(true) implies (x is String) 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] [R|Contract description]
< <
CallsInPlace(init, EXACTLY_ONCE) 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|() ^buildAnnotationArgumentMapping R|/FirAnnotationArgumentMappingBuilder.FirAnnotationArgumentMappingBuilder|().R|kotlin/apply|<R|FirAnnotationArgumentMappingBuilder|>(R|<local>/init|).R|/FirAnnotationArgumentMappingBuilder.build|()
} }
public final class FirAnnotationArgumentMapping : R|kotlin/Any| { public final class FirAnnotationArgumentMapping : R|kotlin/Any| {
@@ -8,6 +8,7 @@ class FirAnnotationArgumentMappingBuilder {
} }
} }
@OptIn(ExperimentalContracts::class)
fun buildAnnotationArgumentMapping(init: FirAnnotationArgumentMappingBuilder.() -> Unit): FirAnnotationArgumentMapping { fun buildAnnotationArgumentMapping(init: FirAnnotationArgumentMappingBuilder.() -> Unit): FirAnnotationArgumentMapping {
contract { contract {
callsInPlace(init, InvocationKind.EXACTLY_ONCE) 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); 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 @Nested
@TestMetadata("compiler/fir/analysis-tests/testData/resolveWithStdlib/contracts/fromSource/bad/callsInPlace") @TestMetadata("compiler/fir/analysis-tests/testData/resolveWithStdlib/contracts/fromSource/bad/callsInPlace")
@TestDataPath("$PROJECT_ROOT") @TestDataPath("$PROJECT_ROOT")
@@ -5247,6 +5253,12 @@ public class FirDiagnosticTestGenerated extends AbstractFirDiagnosticTest {
public void testPropertyGetter() throws Exception { public void testPropertyGetter() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolveWithStdlib/contracts/fromSource/bad/returnsImplies/propertyGetter.kt"); 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); 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 @Nested
@TestMetadata("compiler/fir/analysis-tests/testData/resolveWithStdlib/contracts/fromSource/bad/callsInPlace") @TestMetadata("compiler/fir/analysis-tests/testData/resolveWithStdlib/contracts/fromSource/bad/callsInPlace")
@TestDataPath("$PROJECT_ROOT") @TestDataPath("$PROJECT_ROOT")
@@ -5247,6 +5253,12 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos
public void testPropertyGetter() throws Exception { public void testPropertyGetter() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolveWithStdlib/contracts/fromSource/bad/returnsImplies/propertyGetter.kt"); 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 qualifiedAccessOrAnnotationCalls: List<FirStatement>
abstract val getClassCalls: List<FirGetClassCall> abstract val getClassCalls: List<FirGetClassCall>
abstract val annotationContainers: List<FirAnnotationContainer> abstract val annotationContainers: List<FirAnnotationContainer>
abstract val isContractBody: Boolean
// Suppress // Suppress
abstract val suppressedDiagnostics: Set<String> abstract val suppressedDiagnostics: Set<String>
@@ -71,6 +72,10 @@ abstract class CheckerContext : MutableDiagnosticContext() {
abstract fun dropAnnotationContainer() abstract fun dropAnnotationContainer()
abstract fun enterContractBody(): CheckerContext
abstract fun exitContractBody(): CheckerContext
override fun isDiagnosticSuppressed(diagnostic: KtDiagnostic): Boolean { override fun isDiagnosticSuppressed(diagnostic: KtDiagnostic): Boolean {
val factory = diagnostic.factory val factory = diagnostic.factory
val name = factory.name val name = factory.name
@@ -23,6 +23,7 @@ class MutableCheckerContext private constructor(
override val qualifiedAccessOrAnnotationCalls: MutableList<FirStatement>, override val qualifiedAccessOrAnnotationCalls: MutableList<FirStatement>,
override val getClassCalls: MutableList<FirGetClassCall>, override val getClassCalls: MutableList<FirGetClassCall>,
override val annotationContainers: MutableList<FirAnnotationContainer>, override val annotationContainers: MutableList<FirAnnotationContainer>,
override var isContractBody: Boolean,
sessionHolder: SessionHolder, sessionHolder: SessionHolder,
returnTypeCalculator: ReturnTypeCalculator, returnTypeCalculator: ReturnTypeCalculator,
override val suppressedDiagnostics: PersistentSet<String>, override val suppressedDiagnostics: PersistentSet<String>,
@@ -36,6 +37,7 @@ class MutableCheckerContext private constructor(
mutableListOf(), mutableListOf(),
mutableListOf(), mutableListOf(),
mutableListOf(), mutableListOf(),
isContractBody = false,
sessionHolder, sessionHolder,
returnTypeCalculator, returnTypeCalculator,
persistentSetOf(), persistentSetOf(),
@@ -51,6 +53,7 @@ class MutableCheckerContext private constructor(
qualifiedAccessOrAnnotationCalls, qualifiedAccessOrAnnotationCalls,
getClassCalls, getClassCalls,
annotationContainers, annotationContainers,
isContractBody,
sessionHolder, sessionHolder,
returnTypeCalculator, returnTypeCalculator,
suppressedDiagnostics, suppressedDiagnostics,
@@ -109,6 +112,7 @@ class MutableCheckerContext private constructor(
qualifiedAccessOrAnnotationCalls, qualifiedAccessOrAnnotationCalls,
getClassCalls, getClassCalls,
annotationContainers, annotationContainers,
isContractBody,
sessionHolder, sessionHolder,
returnTypeCalculator, returnTypeCalculator,
suppressedDiagnostics.addAll(diagnosticNames), suppressedDiagnostics.addAll(diagnosticNames),
@@ -117,4 +121,16 @@ class MutableCheckerContext private constructor(
this.allErrorsSuppressed || allErrorsSuppressed 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 qualifiedAccessOrAnnotationCalls: PersistentList<FirStatement>,
override val getClassCalls: PersistentList<FirGetClassCall>, override val getClassCalls: PersistentList<FirGetClassCall>,
override val annotationContainers: PersistentList<FirAnnotationContainer>, override val annotationContainers: PersistentList<FirAnnotationContainer>,
override val isContractBody: Boolean,
sessionHolder: SessionHolder, sessionHolder: SessionHolder,
returnTypeCalculator: ReturnTypeCalculator, returnTypeCalculator: ReturnTypeCalculator,
override val suppressedDiagnostics: PersistentSet<String>, override val suppressedDiagnostics: PersistentSet<String>,
@@ -38,6 +39,7 @@ class PersistentCheckerContext private constructor(
persistentListOf(), persistentListOf(),
persistentListOf(), persistentListOf(),
persistentListOf(), persistentListOf(),
isContractBody = false,
sessionHolder, sessionHolder,
returnTypeCalculator, returnTypeCalculator,
persistentSetOf(), persistentSetOf(),
@@ -53,6 +55,7 @@ class PersistentCheckerContext private constructor(
qualifiedAccessOrAnnotationCalls, qualifiedAccessOrAnnotationCalls,
getClassCalls, getClassCalls,
annotationContainers, annotationContainers,
isContractBody,
sessionHolder, sessionHolder,
returnTypeCalculator, returnTypeCalculator,
suppressedDiagnostics, suppressedDiagnostics,
@@ -69,6 +72,7 @@ class PersistentCheckerContext private constructor(
qualifiedAccessOrAnnotationCalls, qualifiedAccessOrAnnotationCalls,
getClassCalls, getClassCalls,
annotationContainers, annotationContainers,
isContractBody,
sessionHolder, sessionHolder,
returnTypeCalculator, returnTypeCalculator,
suppressedDiagnostics, suppressedDiagnostics,
@@ -88,6 +92,7 @@ class PersistentCheckerContext private constructor(
this.qualifiedAccessOrAnnotationCalls.add(qualifiedAccessOrAnnotationCall), this.qualifiedAccessOrAnnotationCalls.add(qualifiedAccessOrAnnotationCall),
getClassCalls, getClassCalls,
annotationContainers, annotationContainers,
isContractBody,
sessionHolder, sessionHolder,
returnTypeCalculator, returnTypeCalculator,
suppressedDiagnostics, suppressedDiagnostics,
@@ -107,6 +112,7 @@ class PersistentCheckerContext private constructor(
qualifiedAccessOrAnnotationCalls, qualifiedAccessOrAnnotationCalls,
getClassCalls.add(getClassCall), getClassCalls.add(getClassCall),
annotationContainers, annotationContainers,
isContractBody,
sessionHolder, sessionHolder,
returnTypeCalculator, returnTypeCalculator,
suppressedDiagnostics, suppressedDiagnostics,
@@ -126,6 +132,7 @@ class PersistentCheckerContext private constructor(
qualifiedAccessOrAnnotationCalls, qualifiedAccessOrAnnotationCalls,
getClassCalls, getClassCalls,
annotationContainers.add(annotationContainer), annotationContainers.add(annotationContainer),
isContractBody,
sessionHolder, sessionHolder,
returnTypeCalculator, returnTypeCalculator,
suppressedDiagnostics, suppressedDiagnostics,
@@ -151,6 +158,7 @@ class PersistentCheckerContext private constructor(
qualifiedAccessOrAnnotationCalls, qualifiedAccessOrAnnotationCalls,
getClassCalls, getClassCalls,
annotationContainers, annotationContainers,
isContractBody,
sessionHolder, sessionHolder,
returnTypeCalculator, returnTypeCalculator,
suppressedDiagnostics.addAll(diagnosticNames), suppressedDiagnostics.addAll(diagnosticNames),
@@ -159,4 +167,31 @@ class PersistentCheckerContext private constructor(
this.allErrorsSuppressed || allErrorsSuppressed 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`. // 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 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. // 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<*>?, targetSymbol: FirBasedSymbol<*>?,
context: CheckerContext context: CheckerContext
) { ) {
if (context.isContractBody) return
val calledFunctionSymbol = targetSymbol as? FirNamedFunctionSymbol ?: return val calledFunctionSymbol = targetSymbol as? FirNamedFunctionSymbol ?: return
val argumentMapping = functionCall.resolvedArgumentMapping ?: return val argumentMapping = functionCall.resolvedArgumentMapping ?: return
for ((wrappedArgument, valueParameter) in argumentMapping) { for ((wrappedArgument, valueParameter) in argumentMapping) {
@@ -42,7 +42,7 @@ object FirCastOperatorsChecker : FirTypeOperatorCallChecker() {
reporter.reportOn(expression.source, FirErrors.UNCHECKED_CAST, actualType, targetType, context) reporter.reportOn(expression.source, FirErrors.UNCHECKED_CAST, actualType, targetType, context)
} }
} else if (expression.operation == FirOperation.IS) { } 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) 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.*
import org.jetbrains.kotlin.fir.declarations.builder.buildReceiverParameter import org.jetbrains.kotlin.fir.declarations.builder.buildReceiverParameter
import org.jetbrains.kotlin.fir.expressions.* 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.resolve.defaultType
import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
@@ -166,7 +167,13 @@ abstract class AbstractDiagnosticCollectorVisitor(
override fun visitBlock(block: FirBlock, data: Nothing?) { override fun visitBlock(block: FirBlock, data: Nothing?) {
withAnnotationContainer(block) { 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 { private inline fun <R> withTypeRefAnnotationContainer(annotationContainer: FirTypeRef, block: () -> R): R {
var containingTypeRef = context.annotationContainers.lastOrNull() as? FirResolvedTypeRef var containingTypeRef = context.annotationContainers.lastOrNull() as? FirResolvedTypeRef
while (containingTypeRef != null && containingTypeRef.delegatedTypeRef != annotationContainer) { 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.isSynthetic
import org.jetbrains.kotlin.fir.declarations.utils.visibility import org.jetbrains.kotlin.fir.declarations.utils.visibility
import org.jetbrains.kotlin.fir.expressions.* 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.FirElseIfTrueCondition
import org.jetbrains.kotlin.fir.expressions.impl.FirStubStatement import org.jetbrains.kotlin.fir.expressions.impl.FirStubStatement
import org.jetbrains.kotlin.fir.expressions.impl.FirUnitExpression import org.jetbrains.kotlin.fir.expressions.impl.FirUnitExpression
@@ -660,6 +661,7 @@ class Fir2IrVisitor(
if (this is FirTypeAlias) return null if (this is FirTypeAlias) return null
if (this == FirStubStatement) return null if (this == FirStubStatement) return null
if (this is FirUnitExpression) return convertToIrExpression(this) if (this is FirUnitExpression) return convertToIrExpression(this)
if (this is FirContractCallBlock) return null
if (this is FirBlock) return convertToIrExpression(this) if (this is FirBlock) return convertToIrExpression(this)
return accept(this@Fir2IrVisitor, null) as IrStatement return accept(this@Fir2IrVisitor, null) as IrStatement
} }
@@ -1030,7 +1030,7 @@ class DeclarationsConverter(
annotations += modifiers.annotations annotations += modifiers.annotations
typeParameters += constructorTypeParametersFromConstructedClass(classWrapper.classBuilder.typeParameters) typeParameters += constructorTypeParametersFromConstructedClass(classWrapper.classBuilder.typeParameters)
valueParameters += firValueParameters.map { it.firValueParameter } valueParameters += firValueParameters.map { it.firValueParameter }
val (body, _) = convertFunctionBody(block, null) val (body, _) = convertFunctionBody(block, null, allowLegacyContractDescription = true)
this.body = body this.body = body
context.firFunctionTargets.removeLast() context.firFunctionTargets.removeLast()
}.also { }.also {
@@ -1460,9 +1460,8 @@ class DeclarationsConverter(
if (!isGetter) { if (!isGetter) {
valueParameters += firValueParameters valueParameters += firValueParameters
} }
val allowLegacyContractDescription = outerContractDescription == null
val hasContractEffectList = outerContractDescription != null val bodyWithContractDescription = convertFunctionBody(block, expression, allowLegacyContractDescription)
val bodyWithContractDescription = convertFunctionBody(block, expression, hasContractEffectList)
this.body = bodyWithContractDescription.first this.body = bodyWithContractDescription.first
val contractDescription = outerContractDescription ?: bodyWithContractDescription.second val contractDescription = outerContractDescription ?: bodyWithContractDescription.second
contractDescription?.let { contractDescription?.let {
@@ -1720,8 +1719,8 @@ class DeclarationsConverter(
).map { it.firValueParameter } ).map { it.firValueParameter }
} }
val hasContractEffectList = outerContractDescription != null val allowLegacyContractDescription = outerContractDescription == null && !isLocal
val bodyWithContractDescription = convertFunctionBody(block, expression, hasContractEffectList) val bodyWithContractDescription = convertFunctionBody(block, expression, allowLegacyContractDescription)
this.body = bodyWithContractDescription.first this.body = bodyWithContractDescription.first
val contractDescription = outerContractDescription ?: bodyWithContractDescription.second val contractDescription = outerContractDescription ?: bodyWithContractDescription.second
contractDescription?.let { contractDescription?.let {
@@ -1755,16 +1754,13 @@ class DeclarationsConverter(
private fun convertFunctionBody( private fun convertFunctionBody(
blockNode: LighterASTNode?, blockNode: LighterASTNode?,
expression: LighterASTNode?, expression: LighterASTNode?,
hasContractEffectList: Boolean = false allowLegacyContractDescription: Boolean
): Pair<FirBlock?, FirContractDescription?> { ): Pair<FirBlock?, FirContractDescription?> {
return when { return when {
blockNode != null -> { blockNode != null -> {
val block = convertBlock(blockNode) val block = convertBlock(blockNode)
if (hasContractEffectList) { val contractDescription = runIf(allowLegacyContractDescription) { processLegacyContractDescription(block) }
block to null block to contractDescription
} else {
block.extractContractDescriptionIfPossible()
}
} }
expression != null -> FirSingleExpressionBlock( expression != null -> FirSingleExpressionBlock(
expressionConverter.getAsFirExpression<FirExpression>(expression, "Function has no body (but should)").toReturn() 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()) { if (hasBody()) {
buildOrLazyBlock { buildOrLazyBlock {
if (hasBlockBody()) { if (hasBlockBody()) {
val block = bodyBlockExpression?.accept(this@Visitor, Unit) as? FirBlock val block = bodyBlockExpression?.accept(this@Visitor, Unit) as? FirBlock
return@buildFirBody if (hasContractEffectList()) { val contractDescription = when {
block to null allowLegacyContractDescription && !hasContractEffectList() -> block?.let(::processLegacyContractDescription)
} else { else -> null
block.extractContractDescriptionIfPossible()
} }
return@buildFirBody block to contractDescription
} else { } else {
val result = { bodyExpression }.toFirExpression("Function has no body (but should)") val result = { bodyExpression }.toFirExpression("Function has no body (but should)")
FirSingleExpressionBlock(result.toReturn(baseSource = result.source)) FirSingleExpressionBlock(result.toReturn(baseSource = result.source))
@@ -469,7 +469,7 @@ open class RawFirBuilder(
} }
} }
val outerContractDescription = this@toFirPropertyAccessor.obtainContractDescription() val outerContractDescription = this@toFirPropertyAccessor.obtainContractDescription()
val bodyWithContractDescription = this@toFirPropertyAccessor.buildFirBody() val bodyWithContractDescription = this@toFirPropertyAccessor.buildFirBody(allowLegacyContractDescription = true)
this.body = bodyWithContractDescription.first this.body = bodyWithContractDescription.first
val contractDescription = outerContractDescription ?: bodyWithContractDescription.second val contractDescription = outerContractDescription ?: bodyWithContractDescription.second
contractDescription?.let { contractDescription?.let {
@@ -1417,6 +1417,7 @@ open class RawFirBuilder(
val labelName: String? val labelName: String?
val isAnonymousFunction = function.isAnonymous val isAnonymousFunction = function.isAnonymous
val isLocalFunction = function.isLocal
val functionSymbol: FirFunctionSymbol<*> val functionSymbol: FirFunctionSymbol<*>
val functionBuilder = if (isAnonymousFunction) { val functionBuilder = if (isAnonymousFunction) {
FirAnonymousFunctionBuilder().apply { FirAnonymousFunctionBuilder().apply {
@@ -1435,7 +1436,7 @@ open class RawFirBuilder(
symbol = FirNamedFunctionSymbol(callableIdForName(function.nameAsSafeName)).also { functionSymbol = it } symbol = FirNamedFunctionSymbol(callableIdForName(function.nameAsSafeName)).also { functionSymbol = it }
dispatchReceiverType = currentDispatchReceiverType() dispatchReceiverType = currentDispatchReceiverType()
status = FirDeclarationStatusImpl( status = FirDeclarationStatusImpl(
if (function.isLocal) Visibilities.Local else function.visibility, if (isLocalFunction) Visibilities.Local else function.visibility,
function.modality, function.modality,
).apply { ).apply {
isExpect = function.hasExpectModifier() || context.containerIsExpect isExpect = function.hasExpectModifier() || context.containerIsExpect
@@ -1480,7 +1481,7 @@ open class RawFirBuilder(
listOf() listOf()
withCapturedTypeParameters(true, functionSource, actualTypeParameters) { withCapturedTypeParameters(true, functionSource, actualTypeParameters) {
val outerContractDescription = function.obtainContractDescription() val outerContractDescription = function.obtainContractDescription()
val bodyWithContractDescription = function.buildFirBody() val bodyWithContractDescription = function.buildFirBody(!isLocalFunction)
this.body = bodyWithContractDescription.first this.body = bodyWithContractDescription.first
val contractDescription = outerContractDescription ?: bodyWithContractDescription.second val contractDescription = outerContractDescription ?: bodyWithContractDescription.second
contractDescription?.let { contractDescription?.let {
@@ -1653,7 +1654,7 @@ open class RawFirBuilder(
extractValueParametersTo(this, symbol, ValueParameterDeclaration.FUNCTION) extractValueParametersTo(this, symbol, ValueParameterDeclaration.FUNCTION)
val (body, _) = buildFirBody() val (body, _) = buildFirBody(allowLegacyContractDescription = true)
this.body = body this.body = body
this@RawFirBuilder.context.firFunctionTargets.removeLast() this@RawFirBuilder.context.firFunctionTargets.removeLast()
}.also { }.also {
@@ -7,7 +7,13 @@ FILE: contractDescription.kt
) )
> >
{ {
[StubStatement] {
contract#(<L> = contract@fun <implicit>.<anonymous>(): <implicit> <inline=Unknown> {
callsInPlace#()
}
)
}
test_1#() test_1#()
} }
public? final? fun test_2(): R|kotlin/Unit| 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#() test_2#()
} }
public? final? var test_3: Int = IntegerLiteral(1) 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) ^ IntegerLiteral(1)
} }
public? set(value: Int): R|kotlin/Unit| 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| public? final? fun test_4(): R|kotlin/Unit|
[Contract description] < [Contract description] <
contract#() contract#()
> >
{ {
[StubStatement] {
contract#()
}
test_4#() test_4#()
} }
public? final? fun test_5(): R|kotlin/Unit| { 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.KtNodeTypes
import org.jetbrains.kotlin.fir.FirElement import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.FirFunctionTypeParameter 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.contracts.impl.FirEmptyContractDescription
import org.jetbrains.kotlin.fir.declarations.FirFile import org.jetbrains.kotlin.fir.declarations.FirFile
import org.jetbrains.kotlin.fir.declarations.FirTypeParameter import org.jetbrains.kotlin.fir.declarations.FirTypeParameter
import org.jetbrains.kotlin.fir.declarations.FirValueParameter import org.jetbrains.kotlin.fir.declarations.FirValueParameter
import org.jetbrains.kotlin.fir.declarations.impl.FirResolvedDeclarationStatusImpl import org.jetbrains.kotlin.fir.declarations.impl.FirResolvedDeclarationStatusImpl
import org.jetbrains.kotlin.fir.expressions.* 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.FirNoReceiverExpression
import org.jetbrains.kotlin.fir.expressions.impl.FirStubStatement import org.jetbrains.kotlin.fir.expressions.impl.FirStubStatement
import org.jetbrains.kotlin.fir.references.impl.FirStubReference 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 || if (element is FirTypeRef || element is FirNoReceiverExpression || element is FirTypeParameter ||
element is FirTypeProjection || element is FirValueParameter || element is FirAnnotation || element is FirFunctionTypeParameter || element is FirTypeProjection || element is FirValueParameter || element is FirAnnotation || element is FirFunctionTypeParameter ||
element is FirEmptyContractDescription || element is FirEmptyContractDescription ||
element is FirStubReference || element.isExtensionFunctionAnnotation || element is FirEmptyArgumentList || 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 return
} }
@@ -26,8 +26,8 @@ import org.jetbrains.kotlin.fir.diagnostics.ConeDiagnostic
import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind
import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.expressions.*
import org.jetbrains.kotlin.fir.expressions.builder.* 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.FirSingleExpressionBlock
import org.jetbrains.kotlin.fir.expressions.impl.FirStubStatement
import org.jetbrains.kotlin.fir.references.FirNamedReference import org.jetbrains.kotlin.fir.references.FirNamedReference
import org.jetbrains.kotlin.fir.references.builder.buildDelegateFieldReference import org.jetbrains.kotlin.fir.references.builder.buildDelegateFieldReference
import org.jetbrains.kotlin.fir.references.builder.buildImplicitThisReference import org.jetbrains.kotlin.fir.references.builder.buildImplicitThisReference
@@ -496,14 +496,16 @@ fun <T> FirPropertyBuilder.generateAccessorsByDelegate(
} }
} }
fun FirBlock?.extractContractDescriptionIfPossible(): Pair<FirBlock?, FirContractDescription?> { fun processLegacyContractDescription(block: FirBlock): FirContractDescription? {
if (this == null) return null to null if (block.isContractPresentFirCheck()) {
if (!isContractPresentFirCheck()) return this to null val contractCall = block.replaceFirstStatement<FirFunctionCall> { FirContractCallBlock(it) }
val contractCall = replaceFirstStatement(FirStubStatement) as FirFunctionCall return buildLegacyRawContractDescription {
return this to buildLegacyRawContractDescription { source = contractCall.source
source = contractCall.source this.contractCall = contractCall
this.contractCall = contractCall }
} }
return null
} }
fun FirBlock.isContractPresentFirCheck(): Boolean { 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.buildLegacyRawContractDescription
import org.jetbrains.kotlin.fir.contracts.builder.buildResolvedContractDescription import org.jetbrains.kotlin.fir.contracts.builder.buildResolvedContractDescription
import org.jetbrains.kotlin.fir.contracts.description.ConeEffectDeclaration 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.impl.FirEmptyContractDescription
import org.jetbrains.kotlin.fir.contracts.toFirEffectDeclaration import org.jetbrains.kotlin.fir.contracts.toFirEffectDeclaration
import org.jetbrains.kotlin.fir.declarations.* 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.errorTypeFromPrototype
import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.expressions.*
import org.jetbrains.kotlin.fir.expressions.builder.* 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.moduleData
import org.jetbrains.kotlin.fir.references.builder.buildSimpleNamedReference import org.jetbrains.kotlin.fir.references.builder.buildSimpleNamedReference
import org.jetbrains.kotlin.fir.resolve.ResolutionMode import org.jetbrains.kotlin.fir.resolve.ResolutionMode
@@ -128,35 +130,53 @@ abstract class FirAbstractContractResolveTransformerDispatcher(
} }
} }
private fun <T : FirContractDescriptionOwner> transformContractDescriptionOwner( private fun <T : FirContractDescriptionOwner> transformContractDescriptionOwner(owner: T): T {
owner: T
): T {
dataFlowAnalyzer.enterContractDescription() dataFlowAnalyzer.enterContractDescription()
return when (val contractDescription = owner.contractDescription) { return when (val contractDescription = owner.contractDescription) {
is FirLegacyRawContractDescription -> transformLegacyRawContractDescriptionOwner(owner, contractDescription) is FirLegacyRawContractDescription ->
is FirRawContractDescription -> transformRawContractDescriptionOwner(owner, contractDescription) transformLegacyRawContractDescriptionOwner(owner, contractDescription, hasBodyContract = true)
else -> throw IllegalArgumentException("$owner has a contract description of an unknown type") is FirRawContractDescription ->
transformRawContractDescriptionOwner(owner, contractDescription)
else ->
throw IllegalArgumentException("$owner has a contract description of an unknown type")
} }
} }
private fun <T : FirContractDescriptionOwner> transformLegacyRawContractDescriptionOwner( private fun <T : FirContractDescriptionOwner> transformLegacyRawContractDescriptionOwner(
owner: T, owner: T,
contractDescription: FirLegacyRawContractDescription contractDescription: FirLegacyRawContractDescription,
hasBodyContract: Boolean
): T { ): T {
val valueParameters = owner.valueParameters val valueParameters = owner.valueParameters
for (valueParameter in valueParameters) { for (valueParameter in valueParameters) {
context.storeVariable(valueParameter, session) context.storeVariable(valueParameter, session)
} }
val contractCall = try {
contractMode = false val resolvedContractCall = withContractModeDisabled {
contractDescription.contractCall.transformSingle(transformer, ResolutionMode.ContextIndependent) contractDescription.contractCall
} finally { .transformSingle(transformer, ResolutionMode.ContextIndependent)
contractMode = true .apply { replaceTypeRef(session.builtinTypes.unitType) }
} }
val resolvedId = contractCall.toResolvedCallableSymbol()?.callableId ?: return transformOwnerWithUnresolvedContract(owner)
if (resolvedId != FirContractsDslNames.CONTRACT) return transformOwnerWithUnresolvedContract(owner) if (resolvedContractCall.toResolvedCallableSymbol()?.callableId != FirContractsDslNames.CONTRACT) {
if (contractCall.arguments.size != 1) return transformOwnerOfErrorContract(owner) if (hasBodyContract) {
val argument = contractCall.argument as? FirLambdaArgumentExpression ?: return transformOwnerOfErrorContract(owner) 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 val lambdaBody = (argument.expression as FirAnonymousFunctionExpression).anonymousFunction.body
?: return transformOwnerOfErrorContract(owner) ?: return transformOwnerOfErrorContract(owner)
@@ -165,18 +185,27 @@ abstract class FirAbstractContractResolveTransformerDispatcher(
for (statement in lambdaBody.statements) { for (statement in lambdaBody.statements) {
val effect = statement.accept(effectExtractor, null) as? ConeEffectDeclaration val effect = statement.accept(effectExtractor, null) as? ConeEffectDeclaration
if (effect == null) { if (effect == null) {
unresolvedEffects += statement unresolvedEffects += ConeUnresolvedEffect(statement)
} else { } else {
effects += effect.toFirEffectDeclaration(statement.source) effects += effect.toFirEffectDeclaration(statement.source)
} }
} }
this.source = owner.contractDescription.source this.source = contractDescription.source
} }
owner.replaceContractDescription(resolvedContractDescription) owner.replaceContractDescription(resolvedContractDescription)
dataFlowAnalyzer.exitContractDescription() dataFlowAnalyzer.exitContractDescription()
return owner return owner
} }
private inline fun <T> withContractModeDisabled(block: () -> T): T {
try {
contractMode = false
return block()
} finally {
contractMode = true
}
}
private fun <T : FirContractDescriptionOwner> transformRawContractDescriptionOwner( private fun <T : FirContractDescriptionOwner> transformRawContractDescriptionOwner(
owner: T, owner: T,
contractDescription: FirRawContractDescription contractDescription: FirRawContractDescription
@@ -220,25 +249,7 @@ abstract class FirAbstractContractResolveTransformerDispatcher(
owner.replaceContractDescription(legacyRawContractDescription) owner.replaceContractDescription(legacyRawContractDescription)
return transformLegacyRawContractDescriptionOwner(owner, legacyRawContractDescription) return transformLegacyRawContractDescriptionOwner(owner, legacyRawContractDescription, hasBodyContract = false)
}
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
}
} }
open fun transformDeclarationContent(firClass: FirClass, data: ResolutionMode) { 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.KtSourceElement
import org.jetbrains.kotlin.fir.FirElement 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.* import org.jetbrains.kotlin.fir.visitors.*
/* /*
@@ -18,7 +18,7 @@ import org.jetbrains.kotlin.fir.visitors.*
abstract class FirResolvedContractDescription : FirContractDescription() { abstract class FirResolvedContractDescription : FirContractDescription() {
abstract override val source: KtSourceElement? abstract override val source: KtSourceElement?
abstract val effects: List<FirEffectDeclaration> 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) 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.builder.FirBuilderDsl
import org.jetbrains.kotlin.fir.contracts.FirEffectDeclaration import org.jetbrains.kotlin.fir.contracts.FirEffectDeclaration
import org.jetbrains.kotlin.fir.contracts.FirResolvedContractDescription 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.contracts.impl.FirResolvedContractDescriptionImpl
import org.jetbrains.kotlin.fir.expressions.FirStatement
import org.jetbrains.kotlin.fir.visitors.* import org.jetbrains.kotlin.fir.visitors.*
/* /*
@@ -25,7 +25,7 @@ import org.jetbrains.kotlin.fir.visitors.*
class FirResolvedContractDescriptionBuilder { class FirResolvedContractDescriptionBuilder {
var source: KtSourceElement? = null var source: KtSourceElement? = null
val effects: MutableList<FirEffectDeclaration> = mutableListOf() val effects: MutableList<FirEffectDeclaration> = mutableListOf()
val unresolvedEffects: MutableList<FirStatement> = mutableListOf() val unresolvedEffects: MutableList<ConeUnresolvedEffect> = mutableListOf()
fun build(): FirResolvedContractDescription { fun build(): FirResolvedContractDescription {
return FirResolvedContractDescriptionImpl( return FirResolvedContractDescriptionImpl(
@@ -10,7 +10,7 @@ package org.jetbrains.kotlin.fir.contracts.impl
import org.jetbrains.kotlin.KtSourceElement import org.jetbrains.kotlin.KtSourceElement
import org.jetbrains.kotlin.fir.contracts.FirEffectDeclaration import org.jetbrains.kotlin.fir.contracts.FirEffectDeclaration
import org.jetbrains.kotlin.fir.contracts.FirResolvedContractDescription 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.* import org.jetbrains.kotlin.fir.visitors.*
/* /*
@@ -21,16 +21,14 @@ import org.jetbrains.kotlin.fir.visitors.*
internal class FirResolvedContractDescriptionImpl( internal class FirResolvedContractDescriptionImpl(
override val source: KtSourceElement?, override val source: KtSourceElement?,
override val effects: MutableList<FirEffectDeclaration>, override val effects: MutableList<FirEffectDeclaration>,
override val unresolvedEffects: MutableList<FirStatement>, override val unresolvedEffects: MutableList<ConeUnresolvedEffect>,
) : FirResolvedContractDescription() { ) : FirResolvedContractDescription() {
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) { override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {
effects.forEach { it.accept(visitor, data) } effects.forEach { it.accept(visitor, data) }
unresolvedEffects.forEach { it.accept(visitor, data) }
} }
override fun <D> transformChildren(transformer: FirTransformer<D>, data: D): FirResolvedContractDescriptionImpl { override fun <D> transformChildren(transformer: FirTransformer<D>, data: D): FirResolvedContractDescriptionImpl {
effects.transformInplace(transformer, data) effects.transformInplace(transformer, data)
unresolvedEffects.transformInplace(transformer, data)
return this 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 return this
} }
fun FirBlock.replaceFirstStatement(statement: FirStatement): FirStatement { fun <T : FirStatement> FirBlock.replaceFirstStatement(factory: (T) -> FirStatement): T {
require(this is FirBlockImpl) { require(this is FirBlockImpl) {
"replaceFirstStatement should not be called for ${this::class.simpleName}" "replaceFirstStatement should not be called for ${this::class.simpleName}"
} }
val existed = statements[0] @Suppress("UNCHECKED_CAST")
statements[0] = statement val existing = statements[0] as T
return existed statements[0] = factory(existing)
return existing
} }
fun FirExpression.unwrapArgument(): FirExpression = (this as? FirWrappedArgumentExpression)?.expression ?: this 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 { resolvedContractDescription.configure {
+fieldList("effects", effectDeclaration) +fieldList("effects", effectDeclaration)
+fieldList("unresolvedEffects", statement) +fieldList("unresolvedEffects", coneUnresolvedEffect)
} }
legacyRawContractDescription.configure { legacyRawContractDescription.configure {
@@ -80,6 +80,7 @@ val coneEffectDeclarationType = type("fir.contracts.description", "ConeEffectDec
val emptyContractDescriptionType = generatedType("contracts.impl", "FirEmptyContractDescription") val emptyContractDescriptionType = generatedType("contracts.impl", "FirEmptyContractDescription")
val coneDiagnosticType = generatedType("diagnostics", "ConeDiagnostic") val coneDiagnosticType = generatedType("diagnostics", "ConeDiagnostic")
val coneStubDiagnosticType = generatedType("diagnostics", "ConeStubDiagnostic") val coneStubDiagnosticType = generatedType("diagnostics", "ConeStubDiagnostic")
val coneUnresolvedEffect = type("fir.contracts.description", "ConeUnresolvedEffect")
val dslBuilderAnnotationType = generatedType("builder", "FirBuilderDsl") val dslBuilderAnnotationType = generatedType("builder", "FirBuilderDsl")
val firImplementationDetailType = generatedType("FirImplementationDetail") 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 // with a fake sources for the block which refers to the wrapped expression
object SingleExpressionBlock : KtFakeSourceElementKind() 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.inc()
// x = x++ -> x = { val <unary> = x; x = <unary>.inc(); <unary> } // x = x++ -> x = { val <unary> = x; x = <unary>.inc(); <unary> }
object DesugaredIncrementOrDecrement : KtFakeSourceElementKind() object DesugaredIncrementOrDecrement : KtFakeSourceElementKind()
@@ -156,29 +156,29 @@ fun <T> T?.case_22_3(): Boolean? {
// TESTCASE NUMBER: 23 // TESTCASE NUMBER: 23
fun <T : Number?> T.case_23_1(): Boolean { 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<!>) return !(this@case_23_1 !is Int || <!SENSELESS_COMPARISON!>this@case_23_1 == null<!>)
} }
fun <T : Number?> T.case_23_2(): Boolean? { 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 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? { 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 return if (this@case_23_3 !is Int || <!SENSELESS_COMPARISON!>this@case_23_3 == null<!>) null else true
} }
// TESTCASE NUMBER: 24 // TESTCASE NUMBER: 24
inline fun <reified T : Any?> T?.case_24_1(): Boolean { 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<!>) 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? { 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 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? { 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 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 // TESTCASE NUMBER: 2
fun <T : Number?> T.case_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() if (!(this@case_2 !is Int || <!SENSELESS_COMPARISON!>this@case_2 == null<!>)) throw Exception()
} }
// TESTCASE NUMBER: 3 // TESTCASE NUMBER: 3
inline fun <reified T : Any?> T?.case_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() 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 // TESTCASE NUMBER: 5
fun <T : Number?> T.case_5_1(): Boolean { 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<!> return this@case_5_1 !is Int || <!SENSELESS_COMPARISON!>this@case_5_1 == null<!>
} }
fun <T : Number?> T.case_5_2(): Boolean { 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<!>) return !(this@case_5_2 !is Int || <!SENSELESS_COMPARISON!>this@case_5_2 == null<!>)
} }
fun <T : Number?> T.case_5_3(): Boolean? { 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 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? { 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 return if (this@case_5_4 !is Int || <!SENSELESS_COMPARISON!>this@case_5_4 == null<!>) null else true
} }
// TESTCASE NUMBER: 6 // TESTCASE NUMBER: 6
inline fun <reified T : Any?> T?.case_6_1(): Boolean { 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<!> 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 { 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<!>) 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? { 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 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? { 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 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 // TESTCASE NUMBER: 2
fun <T : Number?> T.case_2(value_2: Any?) { 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() 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 // TESTCASE NUMBER: 3
fun <T : Any?> T?.case_3(value_2: Any?) { 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() 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 // TESTCASE NUMBER: 6
fun <T : Number?> T.case_6_1(value_2: Any?): Boolean { 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<!> 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 { 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<!>) 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? { 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 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? { 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 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 // TESTCASE NUMBER: 7
fun <T : Any?> T?.case_7_1(value_2: Any?): Boolean { 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 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 { 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) 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? { 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 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? { 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 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 // TESTCASE NUMBER: 2
fun <T : Number?> T.case_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() if (!(this@case_2 is Int && <!SENSELESS_COMPARISON!>this@case_2 != null<!>)) throw Exception()
} }
// TESTCASE NUMBER: 3 // TESTCASE NUMBER: 3
inline fun <reified T : Any?> T?.case_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() 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 // TESTCASE NUMBER: 5
fun <T : Number?> T.case_5_1(): Boolean { 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<!> return this@case_5_1 is Int && <!SENSELESS_COMPARISON!>this@case_5_1 != null<!>
} }
fun <T : Number?> T.case_5_2(): Boolean { 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<!>) return !(this@case_5_2 is Int && <!SENSELESS_COMPARISON!>this@case_5_2 != null<!>)
} }
fun <T : Number?> T.case_5_3(): Boolean? { 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 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? { 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 return if (this@case_5_4 is Int && <!SENSELESS_COMPARISON!>this@case_5_4 != null<!>) null else true
} }
// TESTCASE NUMBER: 6 // TESTCASE NUMBER: 6
inline fun <reified T : Any?> T?.case_6_1(): Boolean { 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<!> 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 { 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<!>) 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? { 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 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? { 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 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 // TESTCASE NUMBER: 2
fun <T : Number?> T.case_2(value_2: Any?) { 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() 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 // TESTCASE NUMBER: 3
fun <T : Any?> T?.case_3(value_2: Any?) { 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() 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 // TESTCASE NUMBER: 6
fun <T : Number?> T.case_6_1(value_2: Any?): Boolean { 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<!> 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 { 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<!>) 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? { 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 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? { 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 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 // TESTCASE NUMBER: 7
fun <T : Any?> T?.case_7_1(value_2: Any?): Boolean { 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 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 { 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 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? { 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 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? { 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 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