diff --git a/compiler/fir/analysis-tests/testData/resolve/cfg/innerClassInAnonymousObject.dot b/compiler/fir/analysis-tests/testData/resolve/cfg/innerClassInAnonymousObject.dot index 270a6ac1e59..9a4582e6c35 100644 --- a/compiler/fir/analysis-tests/testData/resolve/cfg/innerClassInAnonymousObject.dot +++ b/compiler/fir/analysis-tests/testData/resolve/cfg/innerClassInAnonymousObject.dot @@ -18,57 +18,56 @@ digraph innerClassInAnonymousObject_kt { } 6 [label="Exit class " style="filled" fillcolor=red]; } - 7 [label="Exit anonymous object"]; - 8 [label="Exit anonymous object expression"]; - 9 [label="Exit property" style="filled" fillcolor=red]; + 7 [label="Exit anonymous object expression"]; + 8 [label="Exit property" style="filled" fillcolor=red]; } subgraph cluster_3 { color=blue - 10 [label="Enter class Nested" style="filled" fillcolor=red]; + 9 [label="Enter class Nested" style="filled" fillcolor=red]; subgraph cluster_4 { color=blue - 11 [label="Enter function " style="filled" fillcolor=red]; - 12 [label="Delegated constructor call: super()" style="filled" fillcolor=yellow]; - 13 [label="Exit function " style="filled" fillcolor=red]; + 10 [label="Enter function " style="filled" fillcolor=red]; + 11 [label="Delegated constructor call: super()" style="filled" fillcolor=yellow]; + 12 [label="Exit function " style="filled" fillcolor=red]; } - 14 [label="Exit class Nested" style="filled" fillcolor=red]; + 13 [label="Exit class Nested" style="filled" fillcolor=red]; } subgraph cluster_5 { color=blue - 15 [label="Enter function foo" style="filled" fillcolor=red]; + 14 [label="Enter function foo" style="filled" fillcolor=red]; subgraph cluster_6 { color=blue - 16 [label="Enter block"]; - 17 [label="Exit block"]; + 15 [label="Enter block"]; + 16 [label="Exit block"]; } - 18 [label="Exit function foo" style="filled" fillcolor=red]; + 17 [label="Exit function foo" style="filled" fillcolor=red]; } 0 -> {1}; 1 -> {2}; - 1 -> {7} [color=red]; + 1 -> {7} [style=dotted]; 1 -> {2} [style=dashed]; 2 -> {3}; - 2 -> {10} [color=red]; + 2 -> {9} [color=red]; 2 -> {6} [style=dotted]; 2 -> {3} [style=dashed]; 3 -> {4}; 4 -> {5}; - 5 -> {6} [color=green]; - 6 -> {7 10} [color=green]; - 6 -> {10} [style=dashed]; + 5 -> {6}; + 6 -> {7}; + 6 -> {9} [color=green]; + 6 -> {9} [style=dashed]; 7 -> {8}; - 8 -> {9}; + 9 -> {10}; + 9 -> {14} [color=red]; + 9 -> {13} [style=dotted]; + 9 -> {10} [style=dashed]; 10 -> {11}; - 10 -> {15} [color=red]; - 10 -> {14} [style=dotted]; - 10 -> {11} [style=dashed]; 11 -> {12}; - 12 -> {13}; + 12 -> {13} [color=green]; 13 -> {14} [color=green]; - 14 -> {15} [color=green]; - 14 -> {15} [style=dashed]; + 13 -> {14} [style=dashed]; + 14 -> {15}; 15 -> {16}; 16 -> {17}; - 17 -> {18}; } diff --git a/compiler/fir/analysis-tests/testData/resolve/cfg/localClassesWithImplicit.dot b/compiler/fir/analysis-tests/testData/resolve/cfg/localClassesWithImplicit.dot index 093b61ce2fa..3bd002ec5b2 100644 --- a/compiler/fir/analysis-tests/testData/resolve/cfg/localClassesWithImplicit.dot +++ b/compiler/fir/analysis-tests/testData/resolve/cfg/localClassesWithImplicit.dot @@ -65,121 +65,120 @@ digraph localClassesWithImplicit_kt { } 28 [label="Exit class " style="filled" fillcolor=red]; } - 29 [label="Exit anonymous object"]; - 30 [label="Exit anonymous object expression"]; - 31 [label="Variable declaration: lval x: R||"]; - 32 [label="Exit block"]; + 29 [label="Exit anonymous object expression"]; + 30 [label="Variable declaration: lval x: R||"]; + 31 [label="Exit block"]; } - 33 [label="Exit function test" style="filled" fillcolor=red]; + 32 [label="Exit function test" style="filled" fillcolor=red]; } subgraph cluster_9 { color=blue - 34 [label="Enter function baz" style="filled" fillcolor=red]; + 33 [label="Enter function baz" style="filled" fillcolor=red]; subgraph cluster_10 { color=blue - 35 [label="Enter block"]; - 36 [label="Const: Int(1)"]; - 37 [label="Jump: ^baz Int(1)"]; - 38 [label="Stub" style="filled" fillcolor=gray]; - 39 [label="Exit block" style="filled" fillcolor=gray]; + 34 [label="Enter block"]; + 35 [label="Const: Int(1)"]; + 36 [label="Jump: ^baz Int(1)"]; + 37 [label="Stub" style="filled" fillcolor=gray]; + 38 [label="Exit block" style="filled" fillcolor=gray]; } - 40 [label="Exit function baz" style="filled" fillcolor=red]; + 39 [label="Exit function baz" style="filled" fillcolor=red]; } subgraph cluster_11 { color=blue - 41 [label="Enter function bar" style="filled" fillcolor=red]; + 40 [label="Enter function bar" style="filled" fillcolor=red]; subgraph cluster_12 { color=blue - 42 [label="Enter block"]; - 43 [label="Postponed enter to lambda"]; + 41 [label="Enter block"]; + 42 [label="Postponed enter to lambda"]; subgraph cluster_13 { color=blue - 44 [label="Enter function anonymousFunction" style="filled" fillcolor=red]; + 43 [label="Enter function anonymousFunction" style="filled" fillcolor=red]; subgraph cluster_14 { color=blue - 45 [label="Enter block"]; - 46 [label="Access variable R|/a|"]; - 47 [label="Smart cast: R|/a|"]; - 48 [label="Access variable R|kotlin/String.length|"]; - 49 [label="Access variable R|/b|"]; - 50 [label="Access variable #"]; - 51 [label="Function call: this@R|/|.R|/.baz|()" style="filled" fillcolor=yellow]; - 52 [label="Exit block"]; + 44 [label="Enter block"]; + 45 [label="Access variable R|/a|"]; + 46 [label="Smart cast: R|/a|"]; + 47 [label="Access variable R|kotlin/String.length|"]; + 48 [label="Access variable R|/b|"]; + 49 [label="Access variable #"]; + 50 [label="Function call: this@R|/|.R|/.baz|()" style="filled" fillcolor=yellow]; + 51 [label="Exit block"]; } - 53 [label="Exit function anonymousFunction" style="filled" fillcolor=red]; + 52 [label="Exit function anonymousFunction" style="filled" fillcolor=red]; } - 54 [label="Postponed exit from lambda"]; - 55 [label="Function call: R|/myRun|(...)" style="filled" fillcolor=yellow]; - 56 [label="Jump: ^bar R|/myRun|( = myRun@fun (): R|kotlin/Int| { + 53 [label="Postponed exit from lambda"]; + 54 [label="Function call: R|/myRun|(...)" style="filled" fillcolor=yellow]; + 55 [label="Jump: ^bar R|/myRun|( = myRun@fun (): R|kotlin/Int| { R|/a|.R|kotlin/String.length| R|/b|.# ^ this@R|/|.R|/.baz|() } )"]; - 57 [label="Stub" style="filled" fillcolor=gray]; - 58 [label="Exit block" style="filled" fillcolor=gray]; + 56 [label="Stub" style="filled" fillcolor=gray]; + 57 [label="Exit block" style="filled" fillcolor=gray]; } - 59 [label="Exit function bar" style="filled" fillcolor=red]; + 58 [label="Exit function bar" style="filled" fillcolor=red]; } subgraph cluster_15 { color=blue - 60 [label="Enter function foo" style="filled" fillcolor=red]; + 59 [label="Enter function foo" style="filled" fillcolor=red]; subgraph cluster_16 { color=blue - 61 [label="Enter block"]; - 62 [label="Postponed enter to lambda"]; + 60 [label="Enter block"]; + 61 [label="Postponed enter to lambda"]; subgraph cluster_17 { color=blue - 63 [label="Enter function anonymousFunction" style="filled" fillcolor=red]; + 62 [label="Enter function anonymousFunction" style="filled" fillcolor=red]; subgraph cluster_18 { color=blue - 64 [label="Enter block"]; - 65 [label="Access variable R|/a|"]; - 66 [label="Smart cast: R|/a|"]; - 67 [label="Access variable R|kotlin/String.length|"]; + 63 [label="Enter block"]; + 64 [label="Access variable R|/a|"]; + 65 [label="Smart cast: R|/a|"]; + 66 [label="Access variable R|kotlin/String.length|"]; subgraph cluster_19 { color=blue - 68 [label="Enter when"]; + 67 [label="Enter when"]; subgraph cluster_20 { color=blue - 69 [label="Enter when branch condition "]; - 70 [label="Access variable R|/b|"]; - 71 [label="Type operator: (R|/b| is R|kotlin/String|)"]; - 72 [label="Exit when branch condition"]; + 68 [label="Enter when branch condition "]; + 69 [label="Access variable R|/b|"]; + 70 [label="Type operator: (R|/b| is R|kotlin/String|)"]; + 71 [label="Exit when branch condition"]; } subgraph cluster_21 { color=blue - 73 [label="Enter when branch condition else"]; - 74 [label="Exit when branch condition"]; + 72 [label="Enter when branch condition else"]; + 73 [label="Exit when branch condition"]; } - 75 [label="Enter when branch result"]; + 74 [label="Enter when branch result"]; subgraph cluster_22 { color=blue - 76 [label="Enter block"]; - 77 [label="Const: Int(1)"]; - 78 [label="Exit block"]; + 75 [label="Enter block"]; + 76 [label="Const: Int(1)"]; + 77 [label="Exit block"]; } - 79 [label="Exit when branch result"]; - 80 [label="Enter when branch result"]; + 78 [label="Exit when branch result"]; + 79 [label="Enter when branch result"]; subgraph cluster_23 { color=blue - 81 [label="Enter block"]; - 82 [label="Access variable R|/b|"]; - 83 [label="Smart cast: R|/b|"]; - 84 [label="Access variable R|kotlin/String.length|"]; - 85 [label="Function call: this@R|/|.R|/.bar|()" style="filled" fillcolor=yellow]; - 86 [label="Exit block"]; + 80 [label="Enter block"]; + 81 [label="Access variable R|/b|"]; + 82 [label="Smart cast: R|/b|"]; + 83 [label="Access variable R|kotlin/String.length|"]; + 84 [label="Function call: this@R|/|.R|/.bar|()" style="filled" fillcolor=yellow]; + 85 [label="Exit block"]; } - 87 [label="Exit when branch result"]; - 88 [label="Exit when"]; + 86 [label="Exit when branch result"]; + 87 [label="Exit when"]; } - 89 [label="Exit block"]; + 88 [label="Exit block"]; } - 90 [label="Exit function anonymousFunction" style="filled" fillcolor=red]; + 89 [label="Exit function anonymousFunction" style="filled" fillcolor=red]; } - 91 [label="Postponed exit from lambda"]; - 92 [label="Function call: R|/myRun|(...)" style="filled" fillcolor=yellow]; - 93 [label="Jump: ^foo R|/myRun|( = myRun@fun (): R|kotlin/Int| { + 90 [label="Postponed exit from lambda"]; + 91 [label="Function call: R|/myRun|(...)" style="filled" fillcolor=yellow]; + 92 [label="Jump: ^foo R|/myRun|( = myRun@fun (): R|kotlin/Int| { R|/a|.R|kotlin/String.length| ^ when () { (R|/b| is R|kotlin/String|) -> { @@ -193,130 +192,130 @@ digraph localClassesWithImplicit_kt { } )"]; - 94 [label="Stub" style="filled" fillcolor=gray]; - 95 [label="Exit block" style="filled" fillcolor=gray]; + 93 [label="Stub" style="filled" fillcolor=gray]; + 94 [label="Exit block" style="filled" fillcolor=gray]; } - 96 [label="Exit function foo" style="filled" fillcolor=red]; + 95 [label="Exit function foo" style="filled" fillcolor=red]; } subgraph cluster_24 { color=blue - 97 [label="Enter class A" style="filled" fillcolor=red]; + 96 [label="Enter class A" style="filled" fillcolor=red]; subgraph cluster_25 { color=blue - 98 [label="Enter function " style="filled" fillcolor=red]; - 99 [label="Delegated constructor call: super()" style="filled" fillcolor=yellow]; - 100 [label="Exit function " style="filled" fillcolor=red]; + 97 [label="Enter function " style="filled" fillcolor=red]; + 98 [label="Delegated constructor call: super()" style="filled" fillcolor=yellow]; + 99 [label="Exit function " style="filled" fillcolor=red]; } - 101 [label="Exit class A" style="filled" fillcolor=red]; + 100 [label="Exit class A" style="filled" fillcolor=red]; } subgraph cluster_26 { color=blue - 102 [label="Enter function baz" style="filled" fillcolor=red]; + 101 [label="Enter function baz" style="filled" fillcolor=red]; subgraph cluster_27 { color=blue - 103 [label="Enter block"]; - 104 [label="Const: Int(1)"]; - 105 [label="Jump: ^baz Int(1)"]; - 106 [label="Stub" style="filled" fillcolor=gray]; - 107 [label="Exit block" style="filled" fillcolor=gray]; + 102 [label="Enter block"]; + 103 [label="Const: Int(1)"]; + 104 [label="Jump: ^baz Int(1)"]; + 105 [label="Stub" style="filled" fillcolor=gray]; + 106 [label="Exit block" style="filled" fillcolor=gray]; } - 108 [label="Exit function baz" style="filled" fillcolor=red]; + 107 [label="Exit function baz" style="filled" fillcolor=red]; } subgraph cluster_28 { color=blue - 109 [label="Enter function bar" style="filled" fillcolor=red]; + 108 [label="Enter function bar" style="filled" fillcolor=red]; subgraph cluster_29 { color=blue - 110 [label="Enter block"]; - 111 [label="Postponed enter to lambda"]; + 109 [label="Enter block"]; + 110 [label="Postponed enter to lambda"]; subgraph cluster_30 { color=blue - 112 [label="Enter function anonymousFunction" style="filled" fillcolor=red]; + 111 [label="Enter function anonymousFunction" style="filled" fillcolor=red]; subgraph cluster_31 { color=blue - 113 [label="Enter block"]; - 114 [label="Access variable R|/b|"]; - 115 [label="Access variable #"]; - 116 [label="Access variable R|/a|"]; - 117 [label="Smart cast: R|/a|"]; - 118 [label="Access variable R|kotlin/String.length|"]; - 119 [label="Function call: this@R|/A|.R|/baz|()" style="filled" fillcolor=yellow]; - 120 [label="Exit block"]; + 112 [label="Enter block"]; + 113 [label="Access variable R|/b|"]; + 114 [label="Access variable #"]; + 115 [label="Access variable R|/a|"]; + 116 [label="Smart cast: R|/a|"]; + 117 [label="Access variable R|kotlin/String.length|"]; + 118 [label="Function call: this@R|/A|.R|/baz|()" style="filled" fillcolor=yellow]; + 119 [label="Exit block"]; } - 121 [label="Exit function anonymousFunction" style="filled" fillcolor=red]; + 120 [label="Exit function anonymousFunction" style="filled" fillcolor=red]; } - 122 [label="Postponed exit from lambda"]; - 123 [label="Function call: R|/myRun|(...)" style="filled" fillcolor=yellow]; - 124 [label="Jump: ^bar R|/myRun|( = myRun@fun (): R|kotlin/Int| { + 121 [label="Postponed exit from lambda"]; + 122 [label="Function call: R|/myRun|(...)" style="filled" fillcolor=yellow]; + 123 [label="Jump: ^bar R|/myRun|( = myRun@fun (): R|kotlin/Int| { R|/b|.# R|/a|.R|kotlin/String.length| ^ this@R|/A|.R|/baz|() } )"]; - 125 [label="Stub" style="filled" fillcolor=gray]; - 126 [label="Exit block" style="filled" fillcolor=gray]; + 124 [label="Stub" style="filled" fillcolor=gray]; + 125 [label="Exit block" style="filled" fillcolor=gray]; } - 127 [label="Exit function bar" style="filled" fillcolor=red]; + 126 [label="Exit function bar" style="filled" fillcolor=red]; } subgraph cluster_32 { color=blue - 128 [label="Enter function foo" style="filled" fillcolor=red]; + 127 [label="Enter function foo" style="filled" fillcolor=red]; subgraph cluster_33 { color=blue - 129 [label="Enter block"]; - 130 [label="Postponed enter to lambda"]; + 128 [label="Enter block"]; + 129 [label="Postponed enter to lambda"]; subgraph cluster_34 { color=blue - 131 [label="Enter function anonymousFunction" style="filled" fillcolor=red]; + 130 [label="Enter function anonymousFunction" style="filled" fillcolor=red]; subgraph cluster_35 { color=blue - 132 [label="Enter block"]; - 133 [label="Access variable R|/a|"]; - 134 [label="Smart cast: R|/a|"]; - 135 [label="Access variable R|kotlin/String.length|"]; + 131 [label="Enter block"]; + 132 [label="Access variable R|/a|"]; + 133 [label="Smart cast: R|/a|"]; + 134 [label="Access variable R|kotlin/String.length|"]; subgraph cluster_36 { color=blue - 136 [label="Enter when"]; + 135 [label="Enter when"]; subgraph cluster_37 { color=blue - 137 [label="Enter when branch condition "]; - 138 [label="Access variable R|/b|"]; - 139 [label="Type operator: (R|/b| is R|kotlin/String|)"]; - 140 [label="Exit when branch condition"]; + 136 [label="Enter when branch condition "]; + 137 [label="Access variable R|/b|"]; + 138 [label="Type operator: (R|/b| is R|kotlin/String|)"]; + 139 [label="Exit when branch condition"]; } subgraph cluster_38 { color=blue - 141 [label="Enter when branch condition else"]; - 142 [label="Exit when branch condition"]; + 140 [label="Enter when branch condition else"]; + 141 [label="Exit when branch condition"]; } - 143 [label="Enter when branch result"]; + 142 [label="Enter when branch result"]; subgraph cluster_39 { color=blue - 144 [label="Enter block"]; - 145 [label="Const: Int(1)"]; - 146 [label="Exit block"]; + 143 [label="Enter block"]; + 144 [label="Const: Int(1)"]; + 145 [label="Exit block"]; } - 147 [label="Exit when branch result"]; - 148 [label="Enter when branch result"]; + 146 [label="Exit when branch result"]; + 147 [label="Enter when branch result"]; subgraph cluster_40 { color=blue - 149 [label="Enter block"]; - 150 [label="Access variable R|/b|"]; - 151 [label="Smart cast: R|/b|"]; - 152 [label="Access variable R|kotlin/String.length|"]; - 153 [label="Function call: this@R|/A|.R|/bar|()" style="filled" fillcolor=yellow]; - 154 [label="Exit block"]; + 148 [label="Enter block"]; + 149 [label="Access variable R|/b|"]; + 150 [label="Smart cast: R|/b|"]; + 151 [label="Access variable R|kotlin/String.length|"]; + 152 [label="Function call: this@R|/A|.R|/bar|()" style="filled" fillcolor=yellow]; + 153 [label="Exit block"]; } - 155 [label="Exit when branch result"]; - 156 [label="Exit when"]; + 154 [label="Exit when branch result"]; + 155 [label="Exit when"]; } - 157 [label="Exit block"]; + 156 [label="Exit block"]; } - 158 [label="Exit function anonymousFunction" style="filled" fillcolor=red]; + 157 [label="Exit function anonymousFunction" style="filled" fillcolor=red]; } - 159 [label="Postponed exit from lambda"]; - 160 [label="Function call: R|/myRun|(...)" style="filled" fillcolor=yellow]; - 161 [label="Jump: ^foo R|/myRun|( = myRun@fun (): R|kotlin/Int| { + 158 [label="Postponed exit from lambda"]; + 159 [label="Function call: R|/myRun|(...)" style="filled" fillcolor=yellow]; + 160 [label="Jump: ^foo R|/myRun|( = myRun@fun (): R|kotlin/Int| { R|/a|.R|kotlin/String.length| ^ when () { (R|/b| is R|kotlin/String|) -> { @@ -330,10 +329,10 @@ digraph localClassesWithImplicit_kt { } )"]; - 162 [label="Stub" style="filled" fillcolor=gray]; - 163 [label="Exit block" style="filled" fillcolor=gray]; + 161 [label="Stub" style="filled" fillcolor=gray]; + 162 [label="Exit block" style="filled" fillcolor=gray]; } - 164 [label="Exit function foo" style="filled" fillcolor=red]; + 163 [label="Exit function foo" style="filled" fillcolor=red]; } 7 -> {8}; 8 -> {9}; @@ -345,41 +344,42 @@ digraph localClassesWithImplicit_kt { 14 -> {21}; 15 -> {16}; 16 -> {17}; - 17 -> {33}; + 17 -> {32}; 17 -> {18} [style=dotted]; 18 -> {19} [style=dotted]; 19 -> {20} [style=dotted]; 20 -> {21} [style=dotted]; 21 -> {22}; - 22 -> {23 97}; - 22 -> {97} [style=dashed]; + 22 -> {23 96}; + 22 -> {96} [style=dashed]; 23 -> {24}; - 23 -> {29} [color=red]; + 23 -> {29} [style=dotted]; 23 -> {24} [style=dashed]; 24 -> {25}; - 24 -> {34 41 60} [color=red]; + 24 -> {33 40 59} [color=red]; 24 -> {28} [style=dotted]; 24 -> {25} [style=dashed]; 25 -> {26}; 26 -> {27}; - 27 -> {28} [color=green]; - 28 -> {29 34 41 60} [color=green]; - 28 -> {34 41 60} [style=dashed]; + 27 -> {28}; + 28 -> {29}; + 28 -> {33 40 59} [color=green]; + 28 -> {33 40 59} [style=dashed]; 29 -> {30}; 30 -> {31}; 31 -> {32}; - 32 -> {33}; + 33 -> {34}; 34 -> {35}; 35 -> {36}; - 36 -> {37}; - 37 -> {40}; + 36 -> {39}; + 36 -> {37} [style=dotted]; 37 -> {38} [style=dotted]; 38 -> {39} [style=dotted]; - 39 -> {40} [style=dotted]; + 40 -> {41}; 41 -> {42}; - 42 -> {43}; - 43 -> {44 54 55}; - 43 -> {44} [style=dashed]; + 42 -> {43 53 54}; + 42 -> {43} [style=dashed]; + 43 -> {44}; 44 -> {45}; 45 -> {46}; 46 -> {47}; @@ -390,17 +390,17 @@ digraph localClassesWithImplicit_kt { 51 -> {52}; 52 -> {53}; 53 -> {54}; + 53 -> {42} [color=green style=dashed]; 54 -> {55}; - 54 -> {43} [color=green style=dashed]; - 55 -> {56}; - 56 -> {59}; + 55 -> {58}; + 55 -> {56} [style=dotted]; 56 -> {57} [style=dotted]; 57 -> {58} [style=dotted]; - 58 -> {59} [style=dotted]; + 59 -> {60}; 60 -> {61}; - 61 -> {62}; - 62 -> {63 91 92}; - 62 -> {63} [style=dashed]; + 61 -> {62 90 91}; + 61 -> {62} [style=dashed]; + 62 -> {63}; 63 -> {64}; 64 -> {65}; 65 -> {66}; @@ -409,15 +409,15 @@ digraph localClassesWithImplicit_kt { 68 -> {69}; 69 -> {70}; 70 -> {71}; - 71 -> {72}; - 72 -> {73 80}; + 71 -> {72 79}; + 72 -> {73}; 73 -> {74}; 74 -> {75}; 75 -> {76}; 76 -> {77}; 77 -> {78}; - 78 -> {79}; - 79 -> {88}; + 78 -> {87}; + 79 -> {80}; 80 -> {81}; 81 -> {82}; 82 -> {83}; @@ -429,33 +429,33 @@ digraph localClassesWithImplicit_kt { 88 -> {89}; 89 -> {90}; 90 -> {91}; + 90 -> {61} [color=green style=dashed]; 91 -> {92}; - 91 -> {62} [color=green style=dashed]; - 92 -> {93}; - 93 -> {96}; + 92 -> {95}; + 92 -> {93} [style=dotted]; 93 -> {94} [style=dotted]; 94 -> {95} [style=dotted]; - 95 -> {96} [style=dotted]; + 96 -> {97}; + 96 -> {101 108 127} [color=red]; + 96 -> {100} [style=dotted]; + 96 -> {97} [style=dashed]; 97 -> {98}; - 97 -> {102 109 128} [color=red]; - 97 -> {101} [style=dotted]; - 97 -> {98} [style=dashed]; 98 -> {99}; - 99 -> {100}; - 100 -> {101} [color=green]; - 101 -> {102 109 128} [color=green]; - 101 -> {102 109 128} [style=dashed]; + 99 -> {100} [color=green]; + 100 -> {101 108 127} [color=green]; + 100 -> {101 108 127} [style=dashed]; + 101 -> {102}; 102 -> {103}; 103 -> {104}; - 104 -> {105}; - 105 -> {108}; + 104 -> {107}; + 104 -> {105} [style=dotted]; 105 -> {106} [style=dotted]; 106 -> {107} [style=dotted]; - 107 -> {108} [style=dotted]; + 108 -> {109}; 109 -> {110}; - 110 -> {111}; - 111 -> {112 122 123}; - 111 -> {112} [style=dashed]; + 110 -> {111 121 122}; + 110 -> {111} [style=dashed]; + 111 -> {112}; 112 -> {113}; 113 -> {114}; 114 -> {115}; @@ -466,17 +466,17 @@ digraph localClassesWithImplicit_kt { 119 -> {120}; 120 -> {121}; 121 -> {122}; + 121 -> {110} [color=green style=dashed]; 122 -> {123}; - 122 -> {111} [color=green style=dashed]; - 123 -> {124}; - 124 -> {127}; + 123 -> {126}; + 123 -> {124} [style=dotted]; 124 -> {125} [style=dotted]; 125 -> {126} [style=dotted]; - 126 -> {127} [style=dotted]; + 127 -> {128}; 128 -> {129}; - 129 -> {130}; - 130 -> {131 159 160}; - 130 -> {131} [style=dashed]; + 129 -> {130 158 159}; + 129 -> {130} [style=dashed]; + 130 -> {131}; 131 -> {132}; 132 -> {133}; 133 -> {134}; @@ -485,15 +485,15 @@ digraph localClassesWithImplicit_kt { 136 -> {137}; 137 -> {138}; 138 -> {139}; - 139 -> {140}; - 140 -> {141 148}; + 139 -> {140 147}; + 140 -> {141}; 141 -> {142}; 142 -> {143}; 143 -> {144}; 144 -> {145}; 145 -> {146}; - 146 -> {147}; - 147 -> {156}; + 146 -> {155}; + 147 -> {148}; 148 -> {149}; 149 -> {150}; 150 -> {151}; @@ -505,12 +505,11 @@ digraph localClassesWithImplicit_kt { 156 -> {157}; 157 -> {158}; 158 -> {159}; + 158 -> {129} [color=green style=dashed]; 159 -> {160}; - 159 -> {130} [color=green style=dashed]; - 160 -> {161}; - 161 -> {164}; + 160 -> {163}; + 160 -> {161} [style=dotted]; 161 -> {162} [style=dotted]; 162 -> {163} [style=dotted]; - 163 -> {164} [style=dotted]; } diff --git a/compiler/fir/analysis-tests/testData/resolve/smartcasts/smartcastInByClause.dot b/compiler/fir/analysis-tests/testData/resolve/smartcasts/smartcastInByClause.dot index 9b789ce4326..c4bfd55cb50 100644 --- a/compiler/fir/analysis-tests/testData/resolve/smartcasts/smartcastInByClause.dot +++ b/compiler/fir/analysis-tests/testData/resolve/smartcasts/smartcastInByClause.dot @@ -124,9 +124,8 @@ digraph smartcastInByClause_kt { } 55 [label="Exit class " style="filled" fillcolor=red]; } - 56 [label="Exit anonymous object"]; - 57 [label="Exit anonymous object expression"]; - 58 [label="Jump: ^test object : R|Base| { + 56 [label="Exit anonymous object expression"]; + 57 [label="Jump: ^test object : R|Base| { private constructor(): R|| { super() } @@ -142,24 +141,24 @@ digraph smartcastInByClause_kt { } "]; - 59 [label="Stub" style="filled" fillcolor=gray]; - 60 [label="Exit block" style="filled" fillcolor=gray]; + 58 [label="Stub" style="filled" fillcolor=gray]; + 59 [label="Exit block" style="filled" fillcolor=gray]; } - 61 [label="Exit function test" style="filled" fillcolor=red]; + 60 [label="Exit function test" style="filled" fillcolor=red]; } subgraph cluster_14 { color=blue - 62 [label="Enter function foo" style="filled" fillcolor=red]; + 61 [label="Enter function foo" style="filled" fillcolor=red]; subgraph cluster_15 { color=blue - 63 [label="Enter block"]; - 64 [label="Access variable R|/a|"]; - 65 [label="Smart cast: R|/a|"]; - 66 [label="Access variable R|/A.index|"]; - 67 [label="Function call: R|/takeInt|(...)" style="filled" fillcolor=yellow]; - 68 [label="Exit block"]; + 62 [label="Enter block"]; + 63 [label="Access variable R|/a|"]; + 64 [label="Smart cast: R|/a|"]; + 65 [label="Access variable R|/A.index|"]; + 66 [label="Function call: R|/takeInt|(...)" style="filled" fillcolor=yellow]; + 67 [label="Exit block"]; } - 69 [label="Exit function foo" style="filled" fillcolor=red]; + 68 [label="Exit function foo" style="filled" fillcolor=red]; } 21 -> {22}; 22 -> {23}; @@ -170,7 +169,7 @@ digraph smartcastInByClause_kt { 27 -> {28 32}; 28 -> {29}; 29 -> {30}; - 30 -> {61}; + 30 -> {60}; 30 -> {31} [style=dotted]; 31 -> {33} [style=dotted]; 32 -> {33}; @@ -181,54 +180,56 @@ digraph smartcastInByClause_kt { 37 -> {38}; 38 -> {39}; 39 -> {40}; - 39 -> {56} [color=red]; + 39 -> {56} [style=dotted]; 39 -> {40} [style=dashed]; 40 -> {41}; - 40 -> {44 50 62} [color=red]; + 40 -> {44 50 61} [color=red]; 40 -> {55} [style=dotted]; 40 -> {41 44 50} [style=dashed]; 41 -> {42}; 42 -> {43}; 43 -> {44} [color=green]; + 43 -> {55} [color=red]; 44 -> {45}; 45 -> {46}; 46 -> {47}; 47 -> {48}; 48 -> {49}; 49 -> {50} [color=green]; + 49 -> {55} [color=red]; 50 -> {51}; 51 -> {52}; 52 -> {53}; 53 -> {54}; - 54 -> {55} [color=green]; - 55 -> {56 62} [color=green]; - 55 -> {62} [style=dashed]; + 54 -> {55}; + 55 -> {56}; + 55 -> {61} [color=green]; + 55 -> {61} [style=dashed]; 56 -> {57}; - 57 -> {58}; - 58 -> {61}; + 57 -> {60}; + 57 -> {58} [style=dotted]; 58 -> {59} [style=dotted]; 59 -> {60} [style=dotted]; - 60 -> {61} [style=dotted]; + 61 -> {62}; 62 -> {63}; 63 -> {64}; 64 -> {65}; 65 -> {66}; 66 -> {67}; 67 -> {68}; - 68 -> {69}; subgraph cluster_16 { color=red - 70 [label="Enter function takeInt" style="filled" fillcolor=red]; + 69 [label="Enter function takeInt" style="filled" fillcolor=red]; subgraph cluster_17 { color=blue - 71 [label="Enter block"]; - 72 [label="Exit block"]; + 70 [label="Enter block"]; + 71 [label="Exit block"]; } - 73 [label="Exit function takeInt" style="filled" fillcolor=red]; + 72 [label="Exit function takeInt" style="filled" fillcolor=red]; } + 69 -> {70}; 70 -> {71}; 71 -> {72}; - 72 -> {73}; } diff --git a/compiler/fir/analysis-tests/testData/resolveWithStdlib/contracts/fromSource/bad/callsInPlace/inAnonymousObject.dot b/compiler/fir/analysis-tests/testData/resolveWithStdlib/contracts/fromSource/bad/callsInPlace/inAnonymousObject.dot index f9cb5406af6..63e41984fe4 100644 --- a/compiler/fir/analysis-tests/testData/resolveWithStdlib/contracts/fromSource/bad/callsInPlace/inAnonymousObject.dot +++ b/compiler/fir/analysis-tests/testData/resolveWithStdlib/contracts/fromSource/bad/callsInPlace/inAnonymousObject.dot @@ -44,62 +44,63 @@ digraph inAnonymousObject_kt { } 18 [label="Exit class " style="filled" fillcolor=red]; } - 19 [label="Exit anonymous object"]; - 20 [label="Exit anonymous object expression"]; - 21 [label="Variable declaration: lval obj: R||"]; - 22 [label="Access variable R|/obj|"]; - 23 [label="Function call: R|/obj|.R|/.run|()" style="filled" fillcolor=yellow]; - 24 [label="Function call: R|/d|.R|SubstitutionOverride|()" style="filled" fillcolor=yellow]; - 25 [label="Exit block"]; + 19 [label="Exit anonymous object expression"]; + 20 [label="Variable declaration: lval obj: R||"]; + 21 [label="Access variable R|/obj|"]; + 22 [label="Function call: R|/obj|.R|/.run|()" style="filled" fillcolor=yellow]; + 23 [label="Function call: R|/d|.R|SubstitutionOverride|()" style="filled" fillcolor=yellow]; + 24 [label="Exit block"]; } - 26 [label="Exit function foo" style="filled" fillcolor=red]; + 25 [label="Exit function foo" style="filled" fillcolor=red]; } subgraph cluster_8 { color=blue - 27 [label="Enter function run" style="filled" fillcolor=red]; + 26 [label="Enter function run" style="filled" fillcolor=red]; subgraph cluster_9 { color=blue - 28 [label="Enter block"]; - 29 [label="Function call: R|/c|.R|SubstitutionOverride|()" style="filled" fillcolor=yellow]; - 30 [label="Exit block"]; + 27 [label="Enter block"]; + 28 [label="Function call: R|/c|.R|SubstitutionOverride|()" style="filled" fillcolor=yellow]; + 29 [label="Exit block"]; } - 31 [label="Exit function run" style="filled" fillcolor=red]; + 30 [label="Exit function run" style="filled" fillcolor=red]; } 0 -> {1}; 1 -> {2}; 2 -> {3}; 3 -> {4}; 4 -> {5}; - 4 -> {19} [color=red]; + 4 -> {19} [style=dotted]; 4 -> {5} [style=dashed]; 5 -> {6}; - 5 -> {9 12 27} [color=red]; + 5 -> {9 12 26} [color=red]; 5 -> {18} [style=dotted]; 5 -> {6 9 12} [style=dashed]; 6 -> {7}; 7 -> {8}; 8 -> {9} [color=green]; + 8 -> {18} [color=red]; 9 -> {10}; 10 -> {11}; 11 -> {12} [color=green]; + 11 -> {18} [color=red]; 12 -> {13}; 13 -> {14}; 14 -> {15}; 15 -> {16}; 16 -> {17}; - 17 -> {18} [color=green]; - 18 -> {19 27} [color=green]; - 18 -> {27} [style=dashed]; + 17 -> {18}; + 18 -> {19}; + 18 -> {26} [color=green]; + 18 -> {26} [style=dashed]; 19 -> {20}; 20 -> {21}; 21 -> {22}; 22 -> {23}; 23 -> {24}; 24 -> {25}; - 25 -> {26}; + 26 -> {27}; 27 -> {28}; 28 -> {29}; 29 -> {30}; - 30 -> {31}; } diff --git a/compiler/fir/analysis-tests/testData/resolveWithStdlib/delegates/delegateWithAnonymousObject.dot b/compiler/fir/analysis-tests/testData/resolveWithStdlib/delegates/delegateWithAnonymousObject.dot index 2ee2b7b73e0..b7dbb983a69 100644 --- a/compiler/fir/analysis-tests/testData/resolveWithStdlib/delegates/delegateWithAnonymousObject.dot +++ b/compiler/fir/analysis-tests/testData/resolveWithStdlib/delegates/delegateWithAnonymousObject.dot @@ -109,144 +109,143 @@ digraph delegateWithAnonymousObject_kt { } 36 [label="Exit class " style="filled" fillcolor=red]; } - 37 [label="Exit anonymous object"]; - 38 [label="Exit anonymous object expression"]; - 39 [label="Exit block"]; + 37 [label="Exit anonymous object expression"]; + 38 [label="Exit block"]; } - 40 [label="Exit function anonymousFunction" style="filled" fillcolor=red]; + 39 [label="Exit function anonymousFunction" style="filled" fillcolor=red]; } subgraph cluster_15 { color=blue - 41 [label="Enter function setValue" style="filled" fillcolor=red]; + 40 [label="Enter function setValue" style="filled" fillcolor=red]; subgraph cluster_16 { color=blue - 42 [label="Enter block"]; - 43 [label="Function call: R|/IssueListView.IssueListView|()" style="filled" fillcolor=yellow]; - 44 [label="Access variable R|/value|"]; - 45 [label="Function call: R|/IssueListView.IssueListView|().R|/IssueListView.updateFrom|(...)" style="filled" fillcolor=yellow]; - 46 [label="Jump: ^setValue R|/IssueListView.IssueListView|().R|/IssueListView.updateFrom|(R|/value|)"]; - 47 [label="Stub" style="filled" fillcolor=gray]; - 48 [label="Exit block" style="filled" fillcolor=gray]; + 41 [label="Enter block"]; + 42 [label="Function call: R|/IssueListView.IssueListView|()" style="filled" fillcolor=yellow]; + 43 [label="Access variable R|/value|"]; + 44 [label="Function call: R|/IssueListView.IssueListView|().R|/IssueListView.updateFrom|(...)" style="filled" fillcolor=yellow]; + 45 [label="Jump: ^setValue R|/IssueListView.IssueListView|().R|/IssueListView.updateFrom|(R|/value|)"]; + 46 [label="Stub" style="filled" fillcolor=gray]; + 47 [label="Exit block" style="filled" fillcolor=gray]; } - 49 [label="Exit function setValue" style="filled" fillcolor=red]; + 48 [label="Exit function setValue" style="filled" fillcolor=red]; } subgraph cluster_17 { color=blue - 50 [label="Enter function getValue" style="filled" fillcolor=red]; + 49 [label="Enter function getValue" style="filled" fillcolor=red]; subgraph cluster_18 { color=blue - 51 [label="Enter block"]; - 52 [label="Function call: R|/IssueListView.IssueListView|()" style="filled" fillcolor=yellow]; - 53 [label="Jump: ^getValue R|/IssueListView.IssueListView|()"]; - 54 [label="Stub" style="filled" fillcolor=gray]; - 55 [label="Exit block" style="filled" fillcolor=gray]; + 50 [label="Enter block"]; + 51 [label="Function call: R|/IssueListView.IssueListView|()" style="filled" fillcolor=yellow]; + 52 [label="Jump: ^getValue R|/IssueListView.IssueListView|()"]; + 53 [label="Stub" style="filled" fillcolor=gray]; + 54 [label="Exit block" style="filled" fillcolor=gray]; } - 56 [label="Exit function getValue" style="filled" fillcolor=red]; + 55 [label="Exit function getValue" style="filled" fillcolor=red]; } - 57 [label="Postponed exit from lambda"]; - 58 [label="Function call: this@R|/IssuesListUserProfile|.R|/delegate|(...)" style="filled" fillcolor=yellow]; - 59 [label="Access variable this@R|/IssuesListUserProfile|"]; - 60 [label="Function call: this@R|/IssuesListUserProfile|.R|/delegate|(...).#(...)" style="filled" fillcolor=yellow]; - 61 [label="Exit property delegate" style="filled" fillcolor=yellow]; - 62 [label="Exit property" style="filled" fillcolor=red]; + 56 [label="Postponed exit from lambda"]; + 57 [label="Function call: this@R|/IssuesListUserProfile|.R|/delegate|(...)" style="filled" fillcolor=yellow]; + 58 [label="Access variable this@R|/IssuesListUserProfile|"]; + 59 [label="Function call: this@R|/IssuesListUserProfile|.R|/delegate|(...).#(...)" style="filled" fillcolor=yellow]; + 60 [label="Exit property delegate" style="filled" fillcolor=yellow]; + 61 [label="Exit property" style="filled" fillcolor=red]; } - 63 [label="Exit class IssuesListUserProfile" style="filled" fillcolor=red]; + 62 [label="Exit class IssuesListUserProfile" style="filled" fillcolor=red]; } subgraph cluster_19 { color=blue - 64 [label="Enter function setter" style="filled" fillcolor=red]; + 63 [label="Enter function setter" style="filled" fillcolor=red]; subgraph cluster_20 { color=blue - 65 [label="Enter block"]; - 66 [label="Access variable D|/IssuesListUserProfile.issueListView|"]; - 67 [label="Access variable this@R|/IssuesListUserProfile|"]; - 68 [label="Access variable R|/issueListView|"]; - 69 [label="Function call: this@R|/IssuesListUserProfile|.D|/IssuesListUserProfile.issueListView|.R|SubstitutionOverride|(...)" style="filled" fillcolor=yellow]; - 70 [label="Exit block"]; + 64 [label="Enter block"]; + 65 [label="Access variable D|/IssuesListUserProfile.issueListView|"]; + 66 [label="Access variable this@R|/IssuesListUserProfile|"]; + 67 [label="Access variable R|/issueListView|"]; + 68 [label="Function call: this@R|/IssuesListUserProfile|.D|/IssuesListUserProfile.issueListView|.R|SubstitutionOverride|(...)" style="filled" fillcolor=yellow]; + 69 [label="Exit block"]; } - 71 [label="Exit function setter" style="filled" fillcolor=red]; + 70 [label="Exit function setter" style="filled" fillcolor=red]; } subgraph cluster_21 { color=blue - 72 [label="Enter function getter" style="filled" fillcolor=red]; + 71 [label="Enter function getter" style="filled" fillcolor=red]; subgraph cluster_22 { color=blue - 73 [label="Enter block"]; - 74 [label="Access variable D|/IssuesListUserProfile.issueListView|"]; - 75 [label="Access variable this@R|/IssuesListUserProfile|"]; - 76 [label="Function call: this@R|/IssuesListUserProfile|.D|/IssuesListUserProfile.issueListView|.R|SubstitutionOverride|(...)" style="filled" fillcolor=yellow]; - 77 [label="Jump: ^ this@R|/IssuesListUserProfile|.D|/IssuesListUserProfile.issueListView|.R|SubstitutionOverride|(this@R|/IssuesListUserProfile|, ::R|/IssuesListUserProfile.issueListView|)"]; - 78 [label="Stub" style="filled" fillcolor=gray]; - 79 [label="Exit block" style="filled" fillcolor=gray]; + 72 [label="Enter block"]; + 73 [label="Access variable D|/IssuesListUserProfile.issueListView|"]; + 74 [label="Access variable this@R|/IssuesListUserProfile|"]; + 75 [label="Function call: this@R|/IssuesListUserProfile|.D|/IssuesListUserProfile.issueListView|.R|SubstitutionOverride|(...)" style="filled" fillcolor=yellow]; + 76 [label="Jump: ^ this@R|/IssuesListUserProfile|.D|/IssuesListUserProfile.issueListView|.R|SubstitutionOverride|(this@R|/IssuesListUserProfile|, ::R|/IssuesListUserProfile.issueListView|)"]; + 77 [label="Stub" style="filled" fillcolor=gray]; + 78 [label="Exit block" style="filled" fillcolor=gray]; } - 80 [label="Exit function getter" style="filled" fillcolor=red]; + 79 [label="Exit function getter" style="filled" fillcolor=red]; } 23 -> {24} [color=green]; - 23 -> {63} [style=dotted]; + 23 -> {62} [style=dotted]; 23 -> {24 27} [style=dashed]; 24 -> {25}; 25 -> {26}; 26 -> {27} [color=green]; 27 -> {28}; - 28 -> {29 57 58}; + 28 -> {29 56 57}; 28 -> {29} [style=dashed]; 29 -> {30}; 30 -> {31}; 31 -> {32}; - 31 -> {37} [color=red]; + 31 -> {37} [style=dotted]; 31 -> {32} [style=dashed]; 32 -> {33}; - 32 -> {41 50} [color=red]; + 32 -> {40 49} [color=red]; 32 -> {36} [style=dotted]; 32 -> {33} [style=dashed]; 33 -> {34}; 34 -> {35}; - 35 -> {36} [color=green]; - 36 -> {37 41 50} [color=green]; - 36 -> {41 50} [style=dashed]; + 35 -> {36}; + 36 -> {37}; + 36 -> {40 49} [color=green]; + 36 -> {40 49} [style=dashed]; 37 -> {38}; 38 -> {39}; - 39 -> {40}; + 40 -> {41}; 41 -> {42}; 42 -> {43}; 43 -> {44}; 44 -> {45}; - 45 -> {46}; - 46 -> {49}; + 45 -> {48}; + 45 -> {46} [style=dotted]; 46 -> {47} [style=dotted]; 47 -> {48} [style=dotted]; - 48 -> {49} [style=dotted]; + 49 -> {50}; 50 -> {51}; 51 -> {52}; - 52 -> {53}; - 53 -> {56}; + 52 -> {55}; + 52 -> {53} [style=dotted]; 53 -> {54} [style=dotted]; 54 -> {55} [style=dotted]; - 55 -> {56} [style=dotted]; - 57 -> {58} [color=green]; - 57 -> {61} [color=red]; + 56 -> {57} [color=green]; + 56 -> {60} [color=red]; + 57 -> {58}; 58 -> {59}; 59 -> {60}; 60 -> {61}; - 61 -> {62}; - 62 -> {63} [color=green]; - 63 -> {64 72} [color=green]; - 63 -> {64 72} [style=dashed]; + 61 -> {62} [color=green]; + 62 -> {63 71} [color=green]; + 62 -> {63 71} [style=dashed]; + 63 -> {64}; 64 -> {65}; 65 -> {66}; 66 -> {67}; 67 -> {68}; 68 -> {69}; 69 -> {70}; - 70 -> {71}; + 71 -> {72}; 72 -> {73}; 73 -> {74}; 74 -> {75}; 75 -> {76}; - 76 -> {77}; - 77 -> {80}; + 76 -> {79}; + 76 -> {77} [style=dotted]; 77 -> {78} [style=dotted]; 78 -> {79} [style=dotted]; - 79 -> {80} [style=dotted]; } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraphBuilder.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraphBuilder.kt index 1ed757105b2..d54481abce0 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraphBuilder.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraphBuilder.kt @@ -430,38 +430,15 @@ class ControlFlowGraphBuilder { return localClassEnterNode to enterNode } - fun exitClass(): Pair? { + fun exitClass(): Pair? { if (currentGraph.declaration == null) { levelCounter-- graphs.pop().also { assert(it.kind == ControlFlowGraph.Kind.ClassInitializer) } return null } - val graph = popClassGraph() - val anonymousObject = graph.declaration as? FirAnonymousObject - if (anonymousObject == null || anonymousObject.classKind == ClassKind.ENUM_ENTRY) { - return null to graph - } - - val lastNode = lastNodes.pop() as AnonymousObjectEnterNode - val exitNode = createAnonymousObjectExitNode(lastNode.fir).also { lastNodes.push(it) } - // TODO: should merge data flow from initializer parts into the exit node. - // TODO: the reason for this liveness trickery is that if control flow is dead, the CFG-only edge from - // `graph.exitNode` gets magically transformed into a CFG+DFG dead edge, and `graph.exitNode` has no data - // flow information attached to it. This should be fixed as soon as data flow is made to go through the object. - if (!graph.exitNode.isDead) { - // This implies that `lastNode` is not dead either. - addEdge(graph.exitNode, exitNode, preferredKind = EdgeKind.CfgForward) - addEdge(lastNode, exitNode, preferredKind = EdgeKind.DfgForward) - } else { - addEdge(lastNode, exitNode, isDead = true) - } - return exitNode to graph - } - - // Members of a class can be visited in any order, so data flow between them is unordered - // and we have to recreate the control flow after the fact. - private fun popClassGraph(): ControlFlowGraph { + // Members of a class can be visited in any order, so data flow between them is unordered, + // and we have to recreate the control flow after the fact. assert(currentGraph.kind == ControlFlowGraph.Kind.ClassInitializer) val klass = currentGraph.declaration as FirClass val calledInPlace = mutableListOf() @@ -474,18 +451,24 @@ class ControlFlowGraphBuilder { val enterNode = lastNodes.pop() as ClassEnterNode val exitNode = currentGraph.exitNode as ClassExitNode + // Classes are not initialized in place so no point in merging data flow - it will not be used. + val mergeDataFlow = klass is FirAnonymousObject && klass.classKind != ClassKind.ENUM_ENTRY + val exitKind = if (mergeDataFlow) EdgeKind.Forward else EdgeKind.CfgForward if (calledInPlace.isEmpty()) { - addEdge(enterNode, exitNode, preferredKind = EdgeKind.CfgForward) + addEdge(enterNode, exitNode, preferredKind = exitKind) } else { if (enterNode.previousNodes.isEmpty()) { // Control flow edge to first initializer was only added for local classes. addEdge(enterNode, calledInPlace[0].enterNode, preferredKind = EdgeKind.CfgForward) } val lastInPlace = calledInPlace.reduce { a, b -> + if (mergeDataFlow) { + addEdge(a.exitNode, exitNode, preferredKind = EdgeKind.DfgForward) + } addEdgeToSubGraph(a.exitNode, b.enterNode) b } - addEdge(lastInPlace.exitNode, exitNode, preferredKind = EdgeKind.CfgForward) + addEdge(lastInPlace.exitNode, exitNode, preferredKind = exitKind) // Fake edge to enforce ordering. addEdge(enterNode, exitNode, preferredKind = EdgeKind.DeadForward, propagateDeadness = false) } @@ -503,15 +486,24 @@ class ControlFlowGraphBuilder { enterNode.subGraphs = calledInPlace exitNode.subGraphs = calledLater - return popGraph() + return exitNode.takeIf { mergeDataFlow } to popGraph() } fun exitAnonymousObjectExpression(anonymousObjectExpression: FirAnonymousObjectExpression): AnonymousObjectExpressionExitNode? { - if (anonymousObjectExpression.anonymousObject.classKind == ClassKind.ENUM_ENTRY) return null + val klass = anonymousObjectExpression.anonymousObject + if (klass.classKind == ClassKind.ENUM_ENTRY) return null - // TODO: what's AnonymousObjectExitNode for then? return createAnonymousObjectExpressionExitNode(anonymousObjectExpression).also { - addNewSimpleNodeIfPossible(it) + val exitNode = klass.controlFlowGraphReference?.controlFlowGraph?.exitNode + // TODO: `lastNode` should be `AnonymousObjectEnterNode`, but delegate properties are somewhat broken. + if (exitNode != null && lastNode is AnonymousObjectEnterNode) { + addEdge(exitNode, it) + // Fake edge to enforce ordering. + addEdge(lastNodes.pop(), it, preferredKind = EdgeKind.DeadForward, propagateDeadness = false) + lastNodes.push(it) + } else { + addNewSimpleNode(it) + } } } @@ -1348,11 +1340,6 @@ class ControlFlowGraphBuilder { lastNodes.push(node) } - private fun addNewSimpleNodeIfPossible(newNode: CFGNode<*>) { - if (lastNodes.isEmpty) return - addNewSimpleNode(newNode) - } - private fun addNonTerminatingNode(node: CFGNode<*>) { popAndAddEdge(node) val stub = createStubNode() diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraphNodeBuilder.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraphNodeBuilder.kt index 077a1301805..b06edfa9172 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraphNodeBuilder.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraphNodeBuilder.kt @@ -223,9 +223,6 @@ fun ControlFlowGraphBuilder.createAnonymousFunctionExpressionNode(fir: FirAnonym fun ControlFlowGraphBuilder.createAnonymousObjectEnterNode(fir: FirAnonymousObject): AnonymousObjectEnterNode = AnonymousObjectEnterNode(currentGraph, fir, levelCounter, createId()) -fun ControlFlowGraphBuilder.createAnonymousObjectExitNode(fir: FirAnonymousObject): AnonymousObjectExitNode = - AnonymousObjectExitNode(currentGraph, fir, levelCounter, createId()) - fun ControlFlowGraphBuilder.createAnonymousObjectExpressionExitNode(fir: FirAnonymousObjectExpression): AnonymousObjectExpressionExitNode = AnonymousObjectExpressionExitNode(currentGraph, fir, levelCounter, createId()) diff --git a/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/CFGNode.kt b/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/CFGNode.kt index 290c311f884..303b95c2feb 100644 --- a/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/CFGNode.kt +++ b/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/CFGNode.kt @@ -234,7 +234,7 @@ class ClassEnterNode(owner: ControlFlowGraph, override val fir: FirClass, level: } class ClassExitNode(owner: ControlFlowGraph, override val fir: FirClass, level: Int, id: Int) : CFGNodeWithSubgraphs(owner, level, id), - GraphExitNodeMarker { + GraphExitNodeMarker, UnionNodeMarker { lateinit override var subGraphs: List @@ -255,12 +255,6 @@ class AnonymousObjectEnterNode(owner: ControlFlowGraph, override val fir: FirAno } } -class AnonymousObjectExitNode(owner: ControlFlowGraph, override val fir: FirAnonymousObject, level: Int, id: Int) : CFGNode(owner, level, id) { - override fun accept(visitor: ControlFlowGraphVisitor, data: D): R { - return visitor.visitAnonymousObjectExitNode(this, data) - } -} - class AnonymousObjectExpressionExitNode(owner: ControlFlowGraph, override val fir: FirAnonymousObjectExpression, level: Int, id: Int) : CFGNode(owner, level, id) { override fun accept(visitor: ControlFlowGraphVisitor, data: D): R { return visitor.visitAnonymousObjectExpressionExitNode(this, data) diff --git a/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/CFGNodeRenderer.kt b/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/CFGNodeRenderer.kt index 0da21856ade..d561c323643 100644 --- a/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/CFGNodeRenderer.kt +++ b/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/CFGNodeRenderer.kt @@ -104,7 +104,6 @@ fun CFGNode<*>.render(): String = is ClassExitNode -> "Exit class ${owner.name}" is LocalClassExitNode -> "Exit local class ${owner.name}" is AnonymousObjectEnterNode -> "Enter anonymous object" - is AnonymousObjectExitNode -> "Exit anonymous object" is AnonymousObjectExpressionExitNode -> "Exit anonymous object expression" is ScriptEnterNode -> "Enter class ${fir.name}" diff --git a/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraphVisitor.kt b/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraphVisitor.kt index 1cc8221ebe3..c425cdf96ea 100644 --- a/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraphVisitor.kt +++ b/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraphVisitor.kt @@ -66,10 +66,6 @@ abstract class ControlFlowGraphVisitor { return visitNode(node, data) } - open fun visitAnonymousObjectExitNode(node: AnonymousObjectExitNode, data: D): R { - return visitNode(node, data) - } - open fun visitAnonymousObjectExpressionExitNode(node: AnonymousObjectExpressionExitNode, data: D): R { return visitNode(node, data) } diff --git a/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraphVisitorVoid.kt b/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraphVisitorVoid.kt index dd6f7f835ab..4daa005f205 100644 --- a/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraphVisitorVoid.kt +++ b/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraphVisitorVoid.kt @@ -42,12 +42,6 @@ abstract class ControlFlowGraphVisitorVoid : ControlFlowGraphVisitor+ a } else return -1 } diff --git a/compiler/testData/diagnostics/tests/smartCasts/objectLiterals/exclexcl.fir.kt b/compiler/testData/diagnostics/tests/smartCasts/objectLiterals/exclexcl.fir.kt index 2a0533ed8bb..cd788ad3cf5 100644 --- a/compiler/testData/diagnostics/tests/smartCasts/objectLiterals/exclexcl.fir.kt +++ b/compiler/testData/diagnostics/tests/smartCasts/objectLiterals/exclexcl.fir.kt @@ -15,7 +15,7 @@ fun foo(): Int { k.run() val d: Int = c // a is not null because of k constructor, but we do not know it - return a + d + return a + d } else return -1 } diff --git a/compiler/testData/diagnostics/tests/smartCasts/objectLiterals/exclexclArgument.fir.kt b/compiler/testData/diagnostics/tests/smartCasts/objectLiterals/exclexclArgument.fir.kt index d7f6c5c053d..50e3dbd4626 100644 --- a/compiler/testData/diagnostics/tests/smartCasts/objectLiterals/exclexclArgument.fir.kt +++ b/compiler/testData/diagnostics/tests/smartCasts/objectLiterals/exclexclArgument.fir.kt @@ -11,7 +11,7 @@ fun foo(): Int { } k.run() val d: Int = c - return a + d + return a + d } else return -1 } diff --git a/compiler/testData/diagnostics/tests/smartCasts/objectLiterals/exclexclTwoArgument.fir.kt b/compiler/testData/diagnostics/tests/smartCasts/objectLiterals/exclexclTwoArgument.fir.kt index 994dcfab512..7cdad1eca49 100644 --- a/compiler/testData/diagnostics/tests/smartCasts/objectLiterals/exclexclTwoArgument.fir.kt +++ b/compiler/testData/diagnostics/tests/smartCasts/objectLiterals/exclexclTwoArgument.fir.kt @@ -15,7 +15,7 @@ fun foo(): Int { } k.run() val d: Int = c - return a + d + return a + d } else return -1 } diff --git a/compiler/testData/diagnostics/tests/smartCasts/objectLiterals/kt7110.fir.kt b/compiler/testData/diagnostics/tests/smartCasts/objectLiterals/kt7110.fir.kt index 5f824e2341b..112276e9dff 100644 --- a/compiler/testData/diagnostics/tests/smartCasts/objectLiterals/kt7110.fir.kt +++ b/compiler/testData/diagnostics/tests/smartCasts/objectLiterals/kt7110.fir.kt @@ -7,5 +7,5 @@ abstract class A(val s: String) { fun foo(o: String?): Int { val a = object : A(o!!){} a.bar() - return o.length + return o.length }