diff --git a/compiler/fir/analysis-tests/testData/resolve/cfg/innerClassInAnonymousObject.dot b/compiler/fir/analysis-tests/testData/resolve/cfg/innerClassInAnonymousObject.dot index eb716ff74a8..518382171dd 100644 --- a/compiler/fir/analysis-tests/testData/resolve/cfg/innerClassInAnonymousObject.dot +++ b/compiler/fir/analysis-tests/testData/resolve/cfg/innerClassInAnonymousObject.dot @@ -45,21 +45,26 @@ digraph innerClassInAnonymousObject_kt { subgraph cluster_5 { color=red 14 [label="Enter property" style="filled" fillcolor=red]; - 15 [label="Exit anonymous object"]; - 16 [label="Exit anonymous object expression"]; - 17 [label="Exit property" style="filled" fillcolor=red]; - } - subgraph cluster_6 { - color=blue - 12 [label="Enter class " style="filled" fillcolor=red]; - 13 [label="Exit class " style="filled" fillcolor=red]; + 15 [label="Enter anonymous object"]; + subgraph cluster_6 { + color=blue + 12 [label="Enter class " style="filled" fillcolor=red]; + 13 [label="Exit class " style="filled" fillcolor=red]; + } + 16 [label="Exit anonymous object"]; + 17 [label="Exit anonymous object expression"]; + 18 [label="Exit property" style="filled" fillcolor=red]; } 14 -> {15}; 14 -> {0 3 6} [color=red]; - 15 -> {16}; - 15 -> {0 12} [color=green]; - 15 -> {0 12} [style=dashed]; + 15 -> {16} [color=red]; + 15 -> {12} [color=green]; + 15 -> {12} [style=dashed]; 16 -> {17}; + 16 -> {0} [color=green]; + 16 -> {0} [style=dashed]; + 17 -> {18}; 12 -> {13} [color=green]; + 13 -> {16} [color=green]; } diff --git a/compiler/fir/analysis-tests/testData/resolve/cfg/localClassesWithImplicit.dot b/compiler/fir/analysis-tests/testData/resolve/cfg/localClassesWithImplicit.dot index 5c6ab764584..ee9f73c4c3e 100644 --- a/compiler/fir/analysis-tests/testData/resolve/cfg/localClassesWithImplicit.dot +++ b/compiler/fir/analysis-tests/testData/resolve/cfg/localClassesWithImplicit.dot @@ -53,22 +53,23 @@ digraph localClassesWithImplicit_kt { 21 [label="Exit when"]; } 22 [label="Exit local class test"]; - 23 [label="Exit anonymous object"]; - 24 [label="Exit anonymous object expression"]; - 25 [label="Variable declaration: lval x: R||"]; - 26 [label="Exit block"]; - } - subgraph cluster_7 { - color=blue - 30 [label="Enter class " style="filled" fillcolor=red]; - 31 [label="Exit class " style="filled" fillcolor=red]; + 23 [label="Enter anonymous object"]; + subgraph cluster_7 { + color=blue + 31 [label="Enter class " style="filled" fillcolor=red]; + 32 [label="Exit class " style="filled" fillcolor=red]; + } + 24 [label="Exit anonymous object"]; + 25 [label="Exit anonymous object expression"]; + 26 [label="Variable declaration: lval x: R||"]; + 27 [label="Exit block"]; } subgraph cluster_8 { color=blue - 28 [label="Enter class A" style="filled" fillcolor=red]; - 29 [label="Exit class A" style="filled" fillcolor=red]; + 29 [label="Enter class A" style="filled" fillcolor=red]; + 30 [label="Exit class A" style="filled" fillcolor=red]; } - 27 [label="Exit function test" style="filled" fillcolor=red]; + 28 [label="Exit function test" style="filled" fillcolor=red]; } 7 -> {8}; 8 -> {9}; @@ -80,92 +81,96 @@ digraph localClassesWithImplicit_kt { 14 -> {21}; 15 -> {16}; 16 -> {17}; - 17 -> {27}; + 17 -> {28}; 17 -> {18} [style=dotted]; 18 -> {19} [style=dotted]; 19 -> {20} [style=dotted]; 20 -> {21} [style=dotted]; 21 -> {22}; - 21 -> {32 35 70 88} [color=red]; + 21 -> {33 36 71 89} [color=red]; 22 -> {23}; - 22 -> {95 98 133 151} [color=red]; - 22 -> {32 35 70 88 28} [color=green]; - 22 -> {32 35 70 88 28} [style=dashed]; - 23 -> {24}; - 23 -> {95 98 133 151 30} [color=green]; - 23 -> {95 98 133 151 30} [style=dashed]; + 22 -> {96 99 134 152} [color=red]; + 22 -> {33 36 71 89 29} [color=green]; + 22 -> {33 36 71 89 29} [style=dashed]; + 23 -> {24} [color=red]; + 23 -> {31} [color=green]; + 23 -> {31} [style=dashed]; 24 -> {25}; + 24 -> {96 99 134 152} [color=green]; + 24 -> {96 99 134 152} [style=dashed]; 25 -> {26}; 26 -> {27}; - 28 -> {29} [color=green]; - 30 -> {31} [color=green]; + 27 -> {28}; + 29 -> {30} [color=green]; + 31 -> {32} [color=green]; + 32 -> {24} [color=green]; subgraph cluster_9 { color=red - 32 [label="Enter function " style="filled" fillcolor=red]; - 33 [label="Delegated constructor call: super()"]; - 34 [label="Exit function " style="filled" fillcolor=red]; + 33 [label="Enter function " style="filled" fillcolor=red]; + 34 [label="Delegated constructor call: super()"]; + 35 [label="Exit function " style="filled" fillcolor=red]; } - 32 -> {33}; 33 -> {34}; + 34 -> {35}; subgraph cluster_10 { color=red - 35 [label="Enter function foo" style="filled" fillcolor=red]; + 36 [label="Enter function foo" style="filled" fillcolor=red]; subgraph cluster_11 { color=blue - 36 [label="Enter block"]; - 37 [label="Postponed enter to lambda"]; + 37 [label="Enter block"]; + 38 [label="Postponed enter to lambda"]; subgraph cluster_12 { color=blue - 44 [label="Enter function anonymousFunction" style="filled" fillcolor=red]; + 45 [label="Enter function anonymousFunction" style="filled" fillcolor=red]; subgraph cluster_13 { color=blue - 45 [label="Enter block"]; - 46 [label="Access variable R|/a|"]; - 47 [label="Access variable R|kotlin/String.length|"]; + 46 [label="Enter block"]; + 47 [label="Access variable R|/a|"]; + 48 [label="Access variable R|kotlin/String.length|"]; subgraph cluster_14 { color=blue - 48 [label="Enter when"]; + 49 [label="Enter when"]; subgraph cluster_15 { color=blue - 49 [label="Enter when branch condition "]; - 50 [label="Access variable R|/b|"]; - 51 [label="Type operator: (R|/b| is R|kotlin/String|)"]; - 52 [label="Exit when branch condition"]; + 50 [label="Enter when branch condition "]; + 51 [label="Access variable R|/b|"]; + 52 [label="Type operator: (R|/b| is R|kotlin/String|)"]; + 53 [label="Exit when branch condition"]; } subgraph cluster_16 { color=blue - 53 [label="Enter when branch condition else"]; - 54 [label="Exit when branch condition"]; + 54 [label="Enter when branch condition else"]; + 55 [label="Exit when branch condition"]; } - 55 [label="Enter when branch result"]; + 56 [label="Enter when branch result"]; subgraph cluster_17 { color=blue - 56 [label="Enter block"]; - 57 [label="Const: Int(1)"]; - 58 [label="Exit block"]; + 57 [label="Enter block"]; + 58 [label="Const: Int(1)"]; + 59 [label="Exit block"]; } - 59 [label="Exit when branch result"]; - 60 [label="Enter when branch result"]; + 60 [label="Exit when branch result"]; + 61 [label="Enter when branch result"]; subgraph cluster_18 { color=blue - 61 [label="Enter block"]; - 62 [label="Access variable R|/b|"]; - 63 [label="Access variable R|kotlin/String.length|"]; - 64 [label="Function call: this@R|/A|.R|/bar|()"]; - 65 [label="Exit block"]; + 62 [label="Enter block"]; + 63 [label="Access variable R|/b|"]; + 64 [label="Access variable R|kotlin/String.length|"]; + 65 [label="Function call: this@R|/A|.R|/bar|()"]; + 66 [label="Exit block"]; } - 66 [label="Exit when branch result"]; - 67 [label="Exit when"]; + 67 [label="Exit when branch result"]; + 68 [label="Exit when"]; } - 68 [label="Exit block"]; + 69 [label="Exit block"]; } - 69 [label="Exit function anonymousFunction" style="filled" fillcolor=red]; + 70 [label="Exit function anonymousFunction" style="filled" fillcolor=red]; } - 38 [label="Postponed exit from lambda"]; - 39 [label="Function call: R|/myRun|(...)"]; - 40 [label="Jump: ^foo R|/myRun|( = myRun@fun (): R|kotlin/Int| { + 39 [label="Postponed exit from lambda"]; + 40 [label="Function call: R|/myRun|(...)"]; + 41 [label="Jump: ^foo R|/myRun|( = myRun@fun (): R|kotlin/Int| { R|/a|.R|kotlin/String.length| ^ when () { (R|/b| is R|kotlin/String|) -> { @@ -179,39 +184,38 @@ digraph localClassesWithImplicit_kt { } )"]; - 41 [label="Stub" style="filled" fillcolor=gray]; - 42 [label="Exit block" style="filled" fillcolor=gray]; + 42 [label="Stub" style="filled" fillcolor=gray]; + 43 [label="Exit block" style="filled" fillcolor=gray]; } - 43 [label="Exit function foo" style="filled" fillcolor=red]; + 44 [label="Exit function foo" style="filled" fillcolor=red]; } - 35 -> {36}; 36 -> {37}; - 37 -> {44}; - 37 -> {38} [color=red]; - 37 -> {44} [style=dashed]; - 38 -> {39}; + 37 -> {38}; + 38 -> {45}; + 38 -> {39} [color=red]; + 38 -> {45} [style=dashed]; 39 -> {40}; - 40 -> {43}; - 40 -> {41} [style=dotted]; + 40 -> {41}; + 41 -> {44}; 41 -> {42} [style=dotted]; 42 -> {43} [style=dotted]; - 44 -> {69 45}; - 45 -> {46}; + 43 -> {44} [style=dotted]; + 45 -> {70 46}; 46 -> {47}; 47 -> {48}; 48 -> {49}; 49 -> {50}; 50 -> {51}; 51 -> {52}; - 52 -> {60 53}; - 53 -> {54}; + 52 -> {53}; + 53 -> {61 54}; 54 -> {55}; 55 -> {56}; 56 -> {57}; 57 -> {58}; 58 -> {59}; - 59 -> {67}; - 60 -> {61}; + 59 -> {60}; + 60 -> {68}; 61 -> {62}; 62 -> {63}; 63 -> {64}; @@ -220,153 +224,154 @@ digraph localClassesWithImplicit_kt { 66 -> {67}; 67 -> {68}; 68 -> {69}; - 69 -> {38} [color=green]; - 69 -> {44} [color=green style=dashed]; + 69 -> {70}; + 70 -> {39} [color=green]; + 70 -> {45} [color=green style=dashed]; subgraph cluster_19 { color=red - 70 [label="Enter function bar" style="filled" fillcolor=red]; + 71 [label="Enter function bar" style="filled" fillcolor=red]; subgraph cluster_20 { color=blue - 71 [label="Enter block"]; - 72 [label="Postponed enter to lambda"]; + 72 [label="Enter block"]; + 73 [label="Postponed enter to lambda"]; subgraph cluster_21 { color=blue - 79 [label="Enter function anonymousFunction" style="filled" fillcolor=red]; + 80 [label="Enter function anonymousFunction" style="filled" fillcolor=red]; subgraph cluster_22 { color=blue - 80 [label="Enter block"]; - 81 [label="Access variable R|/b|"]; - 82 [label="Access variable #"]; - 83 [label="Access variable R|/a|"]; - 84 [label="Access variable R|kotlin/String.length|"]; - 85 [label="Function call: this@R|/A|.R|/baz|()"]; - 86 [label="Exit block"]; + 81 [label="Enter block"]; + 82 [label="Access variable R|/b|"]; + 83 [label="Access variable #"]; + 84 [label="Access variable R|/a|"]; + 85 [label="Access variable R|kotlin/String.length|"]; + 86 [label="Function call: this@R|/A|.R|/baz|()"]; + 87 [label="Exit block"]; } - 87 [label="Exit function anonymousFunction" style="filled" fillcolor=red]; + 88 [label="Exit function anonymousFunction" style="filled" fillcolor=red]; } - 73 [label="Postponed exit from lambda"]; - 74 [label="Function call: R|/myRun|(...)"]; - 75 [label="Jump: ^bar R|/myRun|( = myRun@fun (): R|kotlin/Int| { + 74 [label="Postponed exit from lambda"]; + 75 [label="Function call: R|/myRun|(...)"]; + 76 [label="Jump: ^bar R|/myRun|( = myRun@fun (): R|kotlin/Int| { R|/b|.# R|/a|.R|kotlin/String.length| ^ this@R|/A|.R|/baz|() } )"]; - 76 [label="Stub" style="filled" fillcolor=gray]; - 77 [label="Exit block" style="filled" fillcolor=gray]; + 77 [label="Stub" style="filled" fillcolor=gray]; + 78 [label="Exit block" style="filled" fillcolor=gray]; } - 78 [label="Exit function bar" style="filled" fillcolor=red]; + 79 [label="Exit function bar" style="filled" fillcolor=red]; } - 70 -> {71}; 71 -> {72}; - 72 -> {79}; - 72 -> {73} [color=red]; - 72 -> {79} [style=dashed]; - 73 -> {74}; + 72 -> {73}; + 73 -> {80}; + 73 -> {74} [color=red]; + 73 -> {80} [style=dashed]; 74 -> {75}; - 75 -> {78}; - 75 -> {76} [style=dotted]; + 75 -> {76}; + 76 -> {79}; 76 -> {77} [style=dotted]; 77 -> {78} [style=dotted]; - 79 -> {87 80}; - 80 -> {81}; + 78 -> {79} [style=dotted]; + 80 -> {88 81}; 81 -> {82}; 82 -> {83}; 83 -> {84}; 84 -> {85}; 85 -> {86}; 86 -> {87}; - 87 -> {73} [color=green]; - 87 -> {79} [color=green style=dashed]; + 87 -> {88}; + 88 -> {74} [color=green]; + 88 -> {80} [color=green style=dashed]; subgraph cluster_23 { color=red - 88 [label="Enter function baz" style="filled" fillcolor=red]; + 89 [label="Enter function baz" style="filled" fillcolor=red]; subgraph cluster_24 { color=blue - 89 [label="Enter block"]; - 90 [label="Const: Int(1)"]; - 91 [label="Jump: ^baz Int(1)"]; - 92 [label="Stub" style="filled" fillcolor=gray]; - 93 [label="Exit block" style="filled" fillcolor=gray]; + 90 [label="Enter block"]; + 91 [label="Const: Int(1)"]; + 92 [label="Jump: ^baz Int(1)"]; + 93 [label="Stub" style="filled" fillcolor=gray]; + 94 [label="Exit block" style="filled" fillcolor=gray]; } - 94 [label="Exit function baz" style="filled" fillcolor=red]; + 95 [label="Exit function baz" style="filled" fillcolor=red]; } - 88 -> {89}; 89 -> {90}; 90 -> {91}; - 91 -> {94}; - 91 -> {92} [style=dotted]; + 91 -> {92}; + 92 -> {95}; 92 -> {93} [style=dotted]; 93 -> {94} [style=dotted]; + 94 -> {95} [style=dotted]; subgraph cluster_25 { color=red - 95 [label="Enter function " style="filled" fillcolor=red]; - 96 [label="Delegated constructor call: super()"]; - 97 [label="Exit function " style="filled" fillcolor=red]; + 96 [label="Enter function " style="filled" fillcolor=red]; + 97 [label="Delegated constructor call: super()"]; + 98 [label="Exit function " style="filled" fillcolor=red]; } - 95 -> {96}; 96 -> {97}; + 97 -> {98}; subgraph cluster_26 { color=red - 98 [label="Enter function foo" style="filled" fillcolor=red]; + 99 [label="Enter function foo" style="filled" fillcolor=red]; subgraph cluster_27 { color=blue - 99 [label="Enter block"]; - 100 [label="Postponed enter to lambda"]; + 100 [label="Enter block"]; + 101 [label="Postponed enter to lambda"]; subgraph cluster_28 { color=blue - 107 [label="Enter function anonymousFunction" style="filled" fillcolor=red]; + 108 [label="Enter function anonymousFunction" style="filled" fillcolor=red]; subgraph cluster_29 { color=blue - 108 [label="Enter block"]; - 109 [label="Access variable R|/a|"]; - 110 [label="Access variable R|kotlin/String.length|"]; + 109 [label="Enter block"]; + 110 [label="Access variable R|/a|"]; + 111 [label="Access variable R|kotlin/String.length|"]; subgraph cluster_30 { color=blue - 111 [label="Enter when"]; + 112 [label="Enter when"]; subgraph cluster_31 { color=blue - 112 [label="Enter when branch condition "]; - 113 [label="Access variable R|/b|"]; - 114 [label="Type operator: (R|/b| is R|kotlin/String|)"]; - 115 [label="Exit when branch condition"]; + 113 [label="Enter when branch condition "]; + 114 [label="Access variable R|/b|"]; + 115 [label="Type operator: (R|/b| is R|kotlin/String|)"]; + 116 [label="Exit when branch condition"]; } subgraph cluster_32 { color=blue - 116 [label="Enter when branch condition else"]; - 117 [label="Exit when branch condition"]; + 117 [label="Enter when branch condition else"]; + 118 [label="Exit when branch condition"]; } - 118 [label="Enter when branch result"]; + 119 [label="Enter when branch result"]; subgraph cluster_33 { color=blue - 119 [label="Enter block"]; - 120 [label="Const: Int(1)"]; - 121 [label="Exit block"]; + 120 [label="Enter block"]; + 121 [label="Const: Int(1)"]; + 122 [label="Exit block"]; } - 122 [label="Exit when branch result"]; - 123 [label="Enter when branch result"]; + 123 [label="Exit when branch result"]; + 124 [label="Enter when branch result"]; subgraph cluster_34 { color=blue - 124 [label="Enter block"]; - 125 [label="Access variable R|/b|"]; - 126 [label="Access variable R|kotlin/String.length|"]; - 127 [label="Function call: this@R|/|.R|/.bar|()"]; - 128 [label="Exit block"]; + 125 [label="Enter block"]; + 126 [label="Access variable R|/b|"]; + 127 [label="Access variable R|kotlin/String.length|"]; + 128 [label="Function call: this@R|/|.R|/.bar|()"]; + 129 [label="Exit block"]; } - 129 [label="Exit when branch result"]; - 130 [label="Exit when"]; + 130 [label="Exit when branch result"]; + 131 [label="Exit when"]; } - 131 [label="Exit block"]; + 132 [label="Exit block"]; } - 132 [label="Exit function anonymousFunction" style="filled" fillcolor=red]; + 133 [label="Exit function anonymousFunction" style="filled" fillcolor=red]; } - 101 [label="Postponed exit from lambda"]; - 102 [label="Function call: R|/myRun|(...)"]; - 103 [label="Jump: ^foo R|/myRun|( = myRun@fun (): R|kotlin/Int| { + 102 [label="Postponed exit from lambda"]; + 103 [label="Function call: R|/myRun|(...)"]; + 104 [label="Jump: ^foo R|/myRun|( = myRun@fun (): R|kotlin/Int| { R|/a|.R|kotlin/String.length| ^ when () { (R|/b| is R|kotlin/String|) -> { @@ -380,39 +385,38 @@ digraph localClassesWithImplicit_kt { } )"]; - 104 [label="Stub" style="filled" fillcolor=gray]; - 105 [label="Exit block" style="filled" fillcolor=gray]; + 105 [label="Stub" style="filled" fillcolor=gray]; + 106 [label="Exit block" style="filled" fillcolor=gray]; } - 106 [label="Exit function foo" style="filled" fillcolor=red]; + 107 [label="Exit function foo" style="filled" fillcolor=red]; } - 98 -> {99}; 99 -> {100}; - 100 -> {107}; - 100 -> {101} [color=red]; - 100 -> {107} [style=dashed]; - 101 -> {102}; + 100 -> {101}; + 101 -> {108}; + 101 -> {102} [color=red]; + 101 -> {108} [style=dashed]; 102 -> {103}; - 103 -> {106}; - 103 -> {104} [style=dotted]; + 103 -> {104}; + 104 -> {107}; 104 -> {105} [style=dotted]; 105 -> {106} [style=dotted]; - 107 -> {132 108}; - 108 -> {109}; + 106 -> {107} [style=dotted]; + 108 -> {133 109}; 109 -> {110}; 110 -> {111}; 111 -> {112}; 112 -> {113}; 113 -> {114}; 114 -> {115}; - 115 -> {123 116}; - 116 -> {117}; + 115 -> {116}; + 116 -> {124 117}; 117 -> {118}; 118 -> {119}; 119 -> {120}; 120 -> {121}; 121 -> {122}; - 122 -> {130}; - 123 -> {124}; + 122 -> {123}; + 123 -> {131}; 124 -> {125}; 125 -> {126}; 126 -> {127}; @@ -421,85 +425,86 @@ digraph localClassesWithImplicit_kt { 129 -> {130}; 130 -> {131}; 131 -> {132}; - 132 -> {101} [color=green]; - 132 -> {107} [color=green style=dashed]; + 132 -> {133}; + 133 -> {102} [color=green]; + 133 -> {108} [color=green style=dashed]; subgraph cluster_35 { color=red - 133 [label="Enter function bar" style="filled" fillcolor=red]; + 134 [label="Enter function bar" style="filled" fillcolor=red]; subgraph cluster_36 { color=blue - 134 [label="Enter block"]; - 135 [label="Postponed enter to lambda"]; + 135 [label="Enter block"]; + 136 [label="Postponed enter to lambda"]; subgraph cluster_37 { color=blue - 142 [label="Enter function anonymousFunction" style="filled" fillcolor=red]; + 143 [label="Enter function anonymousFunction" style="filled" fillcolor=red]; subgraph cluster_38 { color=blue - 143 [label="Enter block"]; - 144 [label="Access variable R|/a|"]; - 145 [label="Access variable R|kotlin/String.length|"]; - 146 [label="Access variable R|/b|"]; - 147 [label="Access variable #"]; - 148 [label="Function call: this@R|/|.R|/.baz|()"]; - 149 [label="Exit block"]; + 144 [label="Enter block"]; + 145 [label="Access variable R|/a|"]; + 146 [label="Access variable R|kotlin/String.length|"]; + 147 [label="Access variable R|/b|"]; + 148 [label="Access variable #"]; + 149 [label="Function call: this@R|/|.R|/.baz|()"]; + 150 [label="Exit block"]; } - 150 [label="Exit function anonymousFunction" style="filled" fillcolor=red]; + 151 [label="Exit function anonymousFunction" style="filled" fillcolor=red]; } - 136 [label="Postponed exit from lambda"]; - 137 [label="Function call: R|/myRun|(...)"]; - 138 [label="Jump: ^bar R|/myRun|( = myRun@fun (): R|kotlin/Int| { + 137 [label="Postponed exit from lambda"]; + 138 [label="Function call: R|/myRun|(...)"]; + 139 [label="Jump: ^bar R|/myRun|( = myRun@fun (): R|kotlin/Int| { R|/a|.R|kotlin/String.length| R|/b|.# ^ this@R|/|.R|/.baz|() } )"]; - 139 [label="Stub" style="filled" fillcolor=gray]; - 140 [label="Exit block" style="filled" fillcolor=gray]; + 140 [label="Stub" style="filled" fillcolor=gray]; + 141 [label="Exit block" style="filled" fillcolor=gray]; } - 141 [label="Exit function bar" style="filled" fillcolor=red]; + 142 [label="Exit function bar" style="filled" fillcolor=red]; } - 133 -> {134}; 134 -> {135}; - 135 -> {142}; - 135 -> {136} [color=red]; - 135 -> {142} [style=dashed]; - 136 -> {137}; + 135 -> {136}; + 136 -> {143}; + 136 -> {137} [color=red]; + 136 -> {143} [style=dashed]; 137 -> {138}; - 138 -> {141}; - 138 -> {139} [style=dotted]; + 138 -> {139}; + 139 -> {142}; 139 -> {140} [style=dotted]; 140 -> {141} [style=dotted]; - 142 -> {150 143}; - 143 -> {144}; + 141 -> {142} [style=dotted]; + 143 -> {151 144}; 144 -> {145}; 145 -> {146}; 146 -> {147}; 147 -> {148}; 148 -> {149}; 149 -> {150}; - 150 -> {136} [color=green]; - 150 -> {142} [color=green style=dashed]; + 150 -> {151}; + 151 -> {137} [color=green]; + 151 -> {143} [color=green style=dashed]; subgraph cluster_39 { color=red - 151 [label="Enter function baz" style="filled" fillcolor=red]; + 152 [label="Enter function baz" style="filled" fillcolor=red]; subgraph cluster_40 { color=blue - 152 [label="Enter block"]; - 153 [label="Const: Int(1)"]; - 154 [label="Jump: ^baz Int(1)"]; - 155 [label="Stub" style="filled" fillcolor=gray]; - 156 [label="Exit block" style="filled" fillcolor=gray]; + 153 [label="Enter block"]; + 154 [label="Const: Int(1)"]; + 155 [label="Jump: ^baz Int(1)"]; + 156 [label="Stub" style="filled" fillcolor=gray]; + 157 [label="Exit block" style="filled" fillcolor=gray]; } - 157 [label="Exit function baz" style="filled" fillcolor=red]; + 158 [label="Exit function baz" style="filled" fillcolor=red]; } - 151 -> {152}; 152 -> {153}; 153 -> {154}; - 154 -> {157}; - 154 -> {155} [style=dotted]; + 154 -> {155}; + 155 -> {158}; 155 -> {156} [style=dotted]; 156 -> {157} [style=dotted]; + 157 -> {158} [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 f225f3aec8f..6d03396af07 100644 --- a/compiler/fir/analysis-tests/testData/resolve/smartcasts/smartcastInByClause.dot +++ b/compiler/fir/analysis-tests/testData/resolve/smartcasts/smartcastInByClause.dot @@ -105,9 +105,17 @@ digraph smartcastInByClause_kt { 38 [label="Access variable R|/a|"]; 39 [label="Access variable R|/A.index|"]; 40 [label="Function call: R|/takeInt|(...)"]; - 41 [label="Exit anonymous object"]; - 42 [label="Exit anonymous object expression"]; - 43 [label="Jump: ^test object : R|Base| { + 41 [label="Enter anonymous object"]; + subgraph cluster_10 { + color=blue + 48 [label="Enter class " style="filled" fillcolor=red]; + 49 [label="Part of class initialization"]; + 50 [label="Part of class initialization"]; + 51 [label="Exit class " style="filled" fillcolor=red]; + } + 42 [label="Exit anonymous object"]; + 43 [label="Exit anonymous object expression"]; + 44 [label="Jump: ^test object : R|Base| { private constructor(): R|| { super() } @@ -123,17 +131,10 @@ digraph smartcastInByClause_kt { } "]; - 44 [label="Stub" style="filled" fillcolor=gray]; - 45 [label="Exit block" style="filled" fillcolor=gray]; + 45 [label="Stub" style="filled" fillcolor=gray]; + 46 [label="Exit block" style="filled" fillcolor=gray]; } - 46 [label="Exit function test" style="filled" fillcolor=red]; - } - subgraph cluster_10 { - color=blue - 47 [label="Enter class " style="filled" fillcolor=red]; - 48 [label="Part of class initialization"]; - 49 [label="Part of class initialization"]; - 50 [label="Exit class " style="filled" fillcolor=red]; + 47 [label="Exit function test" style="filled" fillcolor=red]; } 24 -> {25}; 25 -> {26}; @@ -146,7 +147,7 @@ digraph smartcastInByClause_kt { 30 -> {35 31}; 31 -> {32}; 32 -> {33}; - 33 -> {46}; + 33 -> {47}; 33 -> {34} [style=dotted]; 34 -> {36} [style=dotted]; 35 -> {36}; @@ -155,90 +156,94 @@ digraph smartcastInByClause_kt { 38 -> {39}; 39 -> {40}; 40 -> {41}; - 40 -> {51 54 59 63} [color=red]; - 41 -> {42}; - 41 -> {51 63 47} [color=green]; - 41 -> {51 63 47} [style=dashed]; + 40 -> {52 55 60 64} [color=red]; + 41 -> {42} [color=red]; + 41 -> {48} [color=green]; + 41 -> {48} [style=dashed]; 42 -> {43}; - 43 -> {46}; - 43 -> {44} [style=dotted]; + 42 -> {52 64} [color=green]; + 42 -> {52 64} [style=dashed]; + 43 -> {44}; + 44 -> {47}; 44 -> {45} [style=dotted]; 45 -> {46} [style=dotted]; - 47 -> {48} [color=green]; - 48 -> {49} [style=dotted]; - 48 -> {54} [color=green]; - 48 -> {54} [style=dashed]; + 46 -> {47} [style=dotted]; + 48 -> {49} [color=green]; 49 -> {50} [style=dotted]; - 49 -> {59} [color=green]; - 49 -> {59} [style=dashed]; + 49 -> {55} [color=green]; + 49 -> {55} [style=dashed]; + 50 -> {51} [style=dotted]; + 50 -> {60} [color=green]; + 50 -> {60} [style=dashed]; + 51 -> {42} [color=green]; subgraph cluster_11 { color=red - 51 [label="Enter function " style="filled" fillcolor=red]; - 52 [label="Delegated constructor call: super()"]; - 53 [label="Exit function " style="filled" fillcolor=red]; + 52 [label="Enter function " style="filled" fillcolor=red]; + 53 [label="Delegated constructor call: super()"]; + 54 [label="Exit function " style="filled" fillcolor=red]; } - 51 -> {52}; 52 -> {53}; + 53 -> {54}; subgraph cluster_12 { color=red - 54 [label="Enter field" style="filled" fillcolor=red]; - 55 [label="Access variable R|/a|"]; - 56 [label="Access variable R|/A.index|"]; - 57 [label="Function call: R|/Derived.Derived|(...)"]; - 58 [label="Exit field" style="filled" fillcolor=red]; + 55 [label="Enter field" style="filled" fillcolor=red]; + 56 [label="Access variable R|/a|"]; + 57 [label="Access variable R|/A.index|"]; + 58 [label="Function call: R|/Derived.Derived|(...)"]; + 59 [label="Exit field" style="filled" fillcolor=red]; } - 54 -> {55}; 55 -> {56}; 56 -> {57}; 57 -> {58}; - 58 -> {49} [color=green]; + 58 -> {59}; + 59 -> {50} [color=green]; subgraph cluster_13 { color=red - 59 [label="Enter property" style="filled" fillcolor=red]; - 60 [label="Access variable R|/a|"]; - 61 [label="Access variable R|/A.index|"]; - 62 [label="Exit property" style="filled" fillcolor=red]; + 60 [label="Enter property" style="filled" fillcolor=red]; + 61 [label="Access variable R|/a|"]; + 62 [label="Access variable R|/A.index|"]; + 63 [label="Exit property" style="filled" fillcolor=red]; } - 59 -> {60}; 60 -> {61}; 61 -> {62}; - 62 -> {50} [color=green]; + 62 -> {63}; + 63 -> {51} [color=green]; subgraph cluster_14 { color=red - 63 [label="Enter function foo" style="filled" fillcolor=red]; + 64 [label="Enter function foo" style="filled" fillcolor=red]; subgraph cluster_15 { color=blue - 64 [label="Enter block"]; - 65 [label="Access variable R|/a|"]; - 66 [label="Access variable R|/A.index|"]; - 67 [label="Function call: R|/takeInt|(...)"]; - 68 [label="Exit block"]; + 65 [label="Enter block"]; + 66 [label="Access variable R|/a|"]; + 67 [label="Access variable R|/A.index|"]; + 68 [label="Function call: R|/takeInt|(...)"]; + 69 [label="Exit block"]; } - 69 [label="Exit function foo" style="filled" fillcolor=red]; + 70 [label="Exit function foo" style="filled" fillcolor=red]; } - 63 -> {64}; 64 -> {65}; 65 -> {66}; 66 -> {67}; 67 -> {68}; 68 -> {69}; + 69 -> {70}; subgraph cluster_16 { color=red - 70 [label="Enter function takeInt" style="filled" fillcolor=red]; + 71 [label="Enter function takeInt" style="filled" fillcolor=red]; subgraph cluster_17 { color=blue - 71 [label="Enter block"]; - 72 [label="Exit block"]; + 72 [label="Enter block"]; + 73 [label="Exit block"]; } - 73 [label="Exit function takeInt" style="filled" fillcolor=red]; + 74 [label="Exit function takeInt" style="filled" fillcolor=red]; } - 70 -> {71}; 71 -> {72}; 72 -> {73}; + 73 -> {74}; } 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 c9d15882863..35553ab1511 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 @@ -9,95 +9,100 @@ digraph inAnonymousObject_kt { subgraph cluster_1 { color=blue 1 [label="Enter block"]; - 2 [label="Exit anonymous object"]; - 3 [label="Exit anonymous object expression"]; - 4 [label="Variable declaration: lval obj: R||"]; - 5 [label="Access variable R|/obj|"]; - 6 [label="Function call: R|/obj|.R|/.run|()"]; - 7 [label="Function call: R|/d|.R|SubstitutionOverride|()"]; - 8 [label="Exit block"]; + 2 [label="Enter anonymous object"]; + subgraph cluster_2 { + color=blue + 11 [label="Enter class " style="filled" fillcolor=red]; + 12 [label="Part of class initialization"]; + 13 [label="Part of class initialization"]; + 14 [label="Exit class " style="filled" fillcolor=red]; + } + 3 [label="Exit anonymous object"]; + 4 [label="Exit anonymous object expression"]; + 5 [label="Variable declaration: lval obj: R||"]; + 6 [label="Access variable R|/obj|"]; + 7 [label="Function call: R|/obj|.R|/.run|()"]; + 8 [label="Function call: R|/d|.R|SubstitutionOverride|()"]; + 9 [label="Exit block"]; } - 9 [label="Exit function foo" style="filled" fillcolor=red]; - } - subgraph cluster_2 { - color=blue - 10 [label="Enter class " style="filled" fillcolor=red]; - 11 [label="Part of class initialization"]; - 12 [label="Part of class initialization"]; - 13 [label="Exit class " style="filled" fillcolor=red]; + 10 [label="Exit function foo" style="filled" fillcolor=red]; } 0 -> {1}; 1 -> {2}; - 1 -> {14 17 20 26} [color=red]; - 2 -> {3}; - 2 -> {14 26 10} [color=green]; - 2 -> {14 26 10} [style=dashed]; + 1 -> {15 18 21 27} [color=red]; + 2 -> {3} [color=red]; + 2 -> {11} [color=green]; + 2 -> {11} [style=dashed]; 3 -> {4}; + 3 -> {15 27} [color=green]; + 3 -> {15 27} [style=dashed]; 4 -> {5}; 5 -> {6}; 6 -> {7}; 7 -> {8}; 8 -> {9}; - 10 -> {11} [color=green]; - 11 -> {12} [style=dotted]; - 11 -> {17} [color=green]; - 11 -> {17} [style=dashed]; + 9 -> {10}; + 11 -> {12} [color=green]; 12 -> {13} [style=dotted]; - 12 -> {20} [color=green]; - 12 -> {20} [style=dashed]; + 12 -> {18} [color=green]; + 12 -> {18} [style=dashed]; + 13 -> {14} [style=dotted]; + 13 -> {21} [color=green]; + 13 -> {21} [style=dashed]; + 14 -> {3} [color=green]; subgraph cluster_3 { color=red - 14 [label="Enter function " style="filled" fillcolor=red]; - 15 [label="Delegated constructor call: super()"]; - 16 [label="Exit function " style="filled" fillcolor=red]; + 15 [label="Enter function " style="filled" fillcolor=red]; + 16 [label="Delegated constructor call: super()"]; + 17 [label="Exit function " style="filled" fillcolor=red]; } - 14 -> {15}; 15 -> {16}; + 16 -> {17}; subgraph cluster_4 { color=red - 17 [label="Enter property" style="filled" fillcolor=red]; - 18 [label="Access variable R|/a|"]; - 19 [label="Exit property" style="filled" fillcolor=red]; + 18 [label="Enter property" style="filled" fillcolor=red]; + 19 [label="Access variable R|/a|"]; + 20 [label="Exit property" style="filled" fillcolor=red]; } - 17 -> {18}; 18 -> {19}; - 19 -> {12} [color=green]; + 19 -> {20}; + 20 -> {13} [color=green]; subgraph cluster_5 { color=red - 20 [label="Enter init block" style="filled" fillcolor=red]; + 21 [label="Enter init block" style="filled" fillcolor=red]; subgraph cluster_6 { color=blue - 21 [label="Enter block"]; - 22 [label="Access variable R|/b|"]; - 23 [label="Assignment: R|/.leaked|"]; - 24 [label="Exit block"]; + 22 [label="Enter block"]; + 23 [label="Access variable R|/b|"]; + 24 [label="Assignment: R|/.leaked|"]; + 25 [label="Exit block"]; } - 25 [label="Exit init block" style="filled" fillcolor=red]; + 26 [label="Exit init block" style="filled" fillcolor=red]; } - 20 -> {21}; 21 -> {22}; 22 -> {23}; 23 -> {24}; 24 -> {25}; - 25 -> {13} [color=green]; + 25 -> {26}; + 26 -> {14} [color=green]; subgraph cluster_7 { color=red - 26 [label="Enter function run" style="filled" fillcolor=red]; + 27 [label="Enter function run" style="filled" fillcolor=red]; subgraph cluster_8 { color=blue - 27 [label="Enter block"]; - 28 [label="Function call: R|/c|.R|SubstitutionOverride|()"]; - 29 [label="Exit block"]; + 28 [label="Enter block"]; + 29 [label="Function call: R|/c|.R|SubstitutionOverride|()"]; + 30 [label="Exit block"]; } - 30 [label="Exit function run" style="filled" fillcolor=red]; + 31 [label="Exit function run" style="filled" fillcolor=red]; } - 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 623a6c7d80e..f207bd82c6a 100644 --- a/compiler/fir/analysis-tests/testData/resolveWithStdlib/delegates/delegateWithAnonymousObject.dot +++ b/compiler/fir/analysis-tests/testData/resolveWithStdlib/delegates/delegateWithAnonymousObject.dot @@ -85,167 +85,172 @@ digraph delegateWithAnonymousObject_kt { subgraph cluster_9 { color=red - 34 [label="Enter function " style="filled" fillcolor=red]; - 35 [label="Delegated constructor call: super()"]; - 36 [label="Exit function " style="filled" fillcolor=red]; + 35 [label="Enter function " style="filled" fillcolor=red]; + 36 [label="Delegated constructor call: super()"]; + 37 [label="Exit function " style="filled" fillcolor=red]; } - 34 -> {35}; 35 -> {36}; + 36 -> {37}; subgraph cluster_10 { color=red - 37 [label="Enter function getValue" style="filled" fillcolor=red]; + 38 [label="Enter function getValue" style="filled" fillcolor=red]; subgraph cluster_11 { color=blue - 38 [label="Enter block"]; - 39 [label="Function call: R|/IssueListView.IssueListView|()"]; - 40 [label="Jump: ^getValue R|/IssueListView.IssueListView|()"]; - 41 [label="Stub" style="filled" fillcolor=gray]; - 42 [label="Exit block" style="filled" fillcolor=gray]; + 39 [label="Enter block"]; + 40 [label="Function call: R|/IssueListView.IssueListView|()"]; + 41 [label="Jump: ^getValue R|/IssueListView.IssueListView|()"]; + 42 [label="Stub" style="filled" fillcolor=gray]; + 43 [label="Exit block" style="filled" fillcolor=gray]; } - 43 [label="Exit function getValue" style="filled" fillcolor=red]; + 44 [label="Exit function getValue" style="filled" fillcolor=red]; } - 37 -> {38}; 38 -> {39}; 39 -> {40}; - 40 -> {43}; - 40 -> {41} [style=dotted]; + 40 -> {41}; + 41 -> {44}; 41 -> {42} [style=dotted]; 42 -> {43} [style=dotted]; + 43 -> {44} [style=dotted]; subgraph cluster_12 { color=red - 44 [label="Enter function setValue" style="filled" fillcolor=red]; + 45 [label="Enter function setValue" style="filled" fillcolor=red]; subgraph cluster_13 { color=blue - 45 [label="Enter block"]; - 46 [label="Function call: R|/IssueListView.IssueListView|()"]; - 47 [label="Access variable R|/value|"]; - 48 [label="Function call: R|/IssueListView.IssueListView|().R|/IssueListView.updateFrom|(...)"]; - 49 [label="Jump: ^setValue R|/IssueListView.IssueListView|().R|/IssueListView.updateFrom|(R|/value|)"]; - 50 [label="Stub" style="filled" fillcolor=gray]; - 51 [label="Exit block" style="filled" fillcolor=gray]; + 46 [label="Enter block"]; + 47 [label="Function call: R|/IssueListView.IssueListView|()"]; + 48 [label="Access variable R|/value|"]; + 49 [label="Function call: R|/IssueListView.IssueListView|().R|/IssueListView.updateFrom|(...)"]; + 50 [label="Jump: ^setValue R|/IssueListView.IssueListView|().R|/IssueListView.updateFrom|(R|/value|)"]; + 51 [label="Stub" style="filled" fillcolor=gray]; + 52 [label="Exit block" style="filled" fillcolor=gray]; } - 52 [label="Exit function setValue" style="filled" fillcolor=red]; + 53 [label="Exit function setValue" style="filled" fillcolor=red]; } - 44 -> {45}; 45 -> {46}; 46 -> {47}; 47 -> {48}; 48 -> {49}; - 49 -> {52}; - 49 -> {50} [style=dotted]; + 49 -> {50}; + 50 -> {53}; 50 -> {51} [style=dotted]; 51 -> {52} [style=dotted]; + 52 -> {53} [style=dotted]; subgraph cluster_14 { color=red - 53 [label="Enter function getter" style="filled" fillcolor=red]; + 54 [label="Enter function getter" style="filled" fillcolor=red]; subgraph cluster_15 { color=blue - 54 [label="Enter block"]; - 55 [label="Access variable D|/IssuesListUserProfile.issueListView|"]; - 56 [label="Access variable this@R|/IssuesListUserProfile|"]; - 57 [label="Function call: this@R|/IssuesListUserProfile|.D|/IssuesListUserProfile.issueListView|.R|SubstitutionOverride|(...)"]; - 58 [label="Jump: ^ this@R|/IssuesListUserProfile|.D|/IssuesListUserProfile.issueListView|.R|SubstitutionOverride|(this@R|/IssuesListUserProfile|, ::R|/IssuesListUserProfile.issueListView|)"]; - 59 [label="Stub" style="filled" fillcolor=gray]; - 60 [label="Exit block" style="filled" fillcolor=gray]; + 55 [label="Enter block"]; + 56 [label="Access variable D|/IssuesListUserProfile.issueListView|"]; + 57 [label="Access variable this@R|/IssuesListUserProfile|"]; + 58 [label="Function call: this@R|/IssuesListUserProfile|.D|/IssuesListUserProfile.issueListView|.R|SubstitutionOverride|(...)"]; + 59 [label="Jump: ^ this@R|/IssuesListUserProfile|.D|/IssuesListUserProfile.issueListView|.R|SubstitutionOverride|(this@R|/IssuesListUserProfile|, ::R|/IssuesListUserProfile.issueListView|)"]; + 60 [label="Stub" style="filled" fillcolor=gray]; + 61 [label="Exit block" style="filled" fillcolor=gray]; } - 61 [label="Exit function getter" style="filled" fillcolor=red]; + 62 [label="Exit function getter" style="filled" fillcolor=red]; } - 53 -> {54}; 54 -> {55}; 55 -> {56}; 56 -> {57}; 57 -> {58}; - 58 -> {61}; - 58 -> {59} [style=dotted]; + 58 -> {59}; + 59 -> {62}; 59 -> {60} [style=dotted]; 60 -> {61} [style=dotted]; + 61 -> {62} [style=dotted]; subgraph cluster_16 { color=red - 62 [label="Enter function setter" style="filled" fillcolor=red]; + 63 [label="Enter function setter" style="filled" fillcolor=red]; subgraph cluster_17 { color=blue - 63 [label="Enter block"]; - 64 [label="Access variable D|/IssuesListUserProfile.issueListView|"]; - 65 [label="Access variable this@R|/IssuesListUserProfile|"]; - 66 [label="Access variable R|/issueListView|"]; - 67 [label="Function call: this@R|/IssuesListUserProfile|.D|/IssuesListUserProfile.issueListView|.R|SubstitutionOverride|(...)"]; - 68 [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|(...)"]; + 69 [label="Exit block"]; } - 69 [label="Exit function setter" style="filled" fillcolor=red]; + 70 [label="Exit function setter" style="filled" fillcolor=red]; } - 62 -> {63}; 63 -> {64}; 64 -> {65}; 65 -> {66}; 66 -> {67}; 67 -> {68}; 68 -> {69}; + 69 -> {70}; subgraph cluster_18 { color=red - 70 [label="Enter property" style="filled" fillcolor=red]; - 71 [label="Postponed enter to lambda"]; - 72 [label="Postponed exit from lambda"]; - 73 [label="Function call: this@R|/IssuesListUserProfile|.R|/delegate|(...)"]; - 74 [label="Access variable this@R|/IssuesListUserProfile|"]; - 75 [label="Function call: this@R|/IssuesListUserProfile|.R|/delegate|(...).#(...)"]; - 76 [label="Postponed enter to lambda"]; + 71 [label="Enter property" style="filled" fillcolor=red]; + 72 [label="Postponed enter to lambda"]; + 73 [label="Postponed exit from lambda"]; + 74 [label="Function call: this@R|/IssuesListUserProfile|.R|/delegate|(...)"]; + 75 [label="Access variable this@R|/IssuesListUserProfile|"]; + 76 [label="Function call: this@R|/IssuesListUserProfile|.R|/delegate|(...).#(...)"]; + 77 [label="Postponed enter to lambda"]; subgraph cluster_19 { color=blue 26 [label="Enter function anonymousFunction" style="filled" fillcolor=red]; subgraph cluster_20 { color=blue 27 [label="Enter block"]; - 28 [label="Exit anonymous object"]; - 29 [label="Exit anonymous object expression"]; - 30 [label="Exit block"]; + 28 [label="Enter anonymous object"]; + subgraph cluster_21 { + color=blue + 33 [label="Enter class " style="filled" fillcolor=red]; + 34 [label="Exit class " style="filled" fillcolor=red]; + } + 29 [label="Exit anonymous object"]; + 30 [label="Exit anonymous object expression"]; + 31 [label="Exit block"]; } - 31 [label="Exit function anonymousFunction" style="filled" fillcolor=red]; + 32 [label="Exit function anonymousFunction" style="filled" fillcolor=red]; } - subgraph cluster_21 { - color=blue - 32 [label="Enter class " style="filled" fillcolor=red]; - 33 [label="Exit class " style="filled" fillcolor=red]; - } - 77 [label="Postponed exit from lambda"]; - 78 [label="Function call: this@R|/IssuesListUserProfile|.R|/delegate|(...)"]; - 79 [label="Exit property" style="filled" fillcolor=red]; + 78 [label="Postponed exit from lambda"]; + 79 [label="Function call: this@R|/IssuesListUserProfile|.R|/delegate|(...)"]; + 80 [label="Exit property" style="filled" fillcolor=red]; } - 70 -> {71}; 71 -> {72}; - 71 -> {} [style=dashed]; 72 -> {73}; + 72 -> {} [style=dashed]; 73 -> {74}; 74 -> {75}; 75 -> {76}; - 76 -> {77 26}; - 76 -> {26} [style=dashed]; - 77 -> {78}; + 76 -> {77}; + 77 -> {78 26}; + 77 -> {26} [style=dashed]; 78 -> {79}; - 79 -> {82} [color=green]; + 79 -> {80}; + 80 -> {83} [color=green]; 26 -> {27}; 27 -> {28}; - 27 -> {34 37 44} [color=red]; - 28 -> {29}; - 28 -> {34 37 44 32} [color=green]; - 28 -> {34 37 44 32} [style=dashed]; + 27 -> {35 38 45} [color=red]; + 28 -> {29} [color=red]; + 28 -> {33} [color=green]; + 28 -> {33} [style=dashed]; 29 -> {30}; + 29 -> {35 38 45} [color=green]; + 29 -> {35 38 45} [style=dashed]; 30 -> {31}; - 32 -> {33} [color=green]; + 31 -> {32}; + 33 -> {34} [color=green]; + 34 -> {29} [color=green]; subgraph cluster_22 { color=red - 80 [label="Enter class IssuesListUserProfile" style="filled" fillcolor=red]; - 81 [label="Part of class initialization"]; - 82 [label="Exit class IssuesListUserProfile" style="filled" fillcolor=red]; + 81 [label="Enter class IssuesListUserProfile" style="filled" fillcolor=red]; + 82 [label="Part of class initialization"]; + 83 [label="Exit class IssuesListUserProfile" style="filled" fillcolor=red]; } - 80 -> {81} [color=green]; - 81 -> {82} [style=dotted]; - 81 -> {70} [color=green]; - 81 -> {70} [style=dashed]; + 81 -> {82} [color=green]; + 82 -> {83} [style=dotted]; + 82 -> {71} [color=green]; + 82 -> {71} [style=dashed]; } diff --git a/compiler/fir/analysis-tests/testData/resolveWithStdlib/initialization/fromLocalMembers.kt b/compiler/fir/analysis-tests/testData/resolveWithStdlib/initialization/fromLocalMembers.kt index 53f34debc9f..1bcf1c82902 100644 --- a/compiler/fir/analysis-tests/testData/resolveWithStdlib/initialization/fromLocalMembers.kt +++ b/compiler/fir/analysis-tests/testData/resolveWithStdlib/initialization/fromLocalMembers.kt @@ -23,8 +23,8 @@ fun test2() { } } - println(x) - println(x) + println(x) + println(x) } fun test3() { diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/cfa/util/CfgTraverser.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/cfa/util/CfgTraverser.kt index 3ce201047ef..13677752b2b 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/cfa/util/CfgTraverser.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/cfa/util/CfgTraverser.kt @@ -20,7 +20,7 @@ fun ControlFlowGraph.traverse( ) { for (node in getNodesInOrder(direction)) { node.accept(visitor, data) - (node as? CFGNodeWithCfgOwner<*>)?.subGraphs?.forEach { it.traverse(direction, visitor, data) } + (node as? CFGNodeWithSubgraphs<*>)?.subGraphs?.forEach { it.traverse(direction, visitor, data) } } } @@ -61,7 +61,7 @@ private fun ControlFlowGraph.collectDataForNodeInternal( ) { val nodes = getNodesInOrder(direction) for (node in nodes) { - if (visitSubGraphs && direction == TraverseDirection.Backward && node is CFGNodeWithCfgOwner<*>) { + if (visitSubGraphs && direction == TraverseDirection.Backward && node is CFGNodeWithSubgraphs<*>) { node.subGraphs.forEach { it.collectDataForNodeInternal(direction, initialInfo, visitor, nodeMap, changed) } } val previousNodes = when (direction) { @@ -85,7 +85,7 @@ private fun ControlFlowGraph.collectDataForNodeInternal( if (hasChanged) { nodeMap[node] = newData } - if (visitSubGraphs && direction == TraverseDirection.Forward && node is CFGNodeWithCfgOwner<*>) { + if (visitSubGraphs && direction == TraverseDirection.Forward && node is CFGNodeWithSubgraphs<*>) { node.subGraphs.forEach { it.collectDataForNodeInternal(direction, initialInfo, visitor, nodeMap, changed) } } } diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/cfa/util/CfgUtils.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/cfa/util/CfgUtils.kt index 6c8f3378b26..1cf1fee5d12 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/cfa/util/CfgUtils.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/cfa/util/CfgUtils.kt @@ -6,7 +6,7 @@ package org.jetbrains.kotlin.fir.analysis.cfa.util import org.jetbrains.kotlin.fir.resolve.dfa.cfg.CFGNode -import org.jetbrains.kotlin.fir.resolve.dfa.cfg.CFGNodeWithCfgOwner +import org.jetbrains.kotlin.fir.resolve.dfa.cfg.CFGNodeWithSubgraphs import org.jetbrains.kotlin.fir.resolve.dfa.cfg.ControlFlowGraph fun ControlFlowGraph.getEnterNode(direction: TraverseDirection): CFGNode<*> = when (direction) { @@ -42,7 +42,7 @@ val CFGNode<*>.followingCfgNodes: List> val kind = outgoingEdges.getValue(it).kind kind.usedInCfa && !kind.isDead } - (this as? CFGNodeWithCfgOwner<*>)?.subGraphs?.mapTo(nodes) { it.enterNode } + (this as? CFGNodeWithSubgraphs<*>)?.subGraphs?.mapTo(nodes) { it.enterNode } return nodes } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/FirDataFlowAnalyzer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/FirDataFlowAnalyzer.kt index 0257b99f08f..6e9a4d4c5a0 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/FirDataFlowAnalyzer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/FirDataFlowAnalyzer.kt @@ -328,6 +328,10 @@ abstract class FirDataFlowAnalyzer( return controlFlowGraph } + fun enterAnonymousObject(anonymousObject: FirAnonymousObject) { + graphBuilder.enterAnonymousObject(anonymousObject).mergeIncomingFlow() + } + fun exitAnonymousObject(anonymousObject: FirAnonymousObject): ControlFlowGraph { // TODO: support capturing of mutable properties, KT-44877 val (node, controlFlowGraph) = graphBuilder.exitAnonymousObject(anonymousObject) 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 6dd36e61246..f8dd4a3db54 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 @@ -453,19 +453,41 @@ class ControlFlowGraphBuilder { return node to graph } + fun enterAnonymousObject(anonymousObject: FirAnonymousObject): AnonymousObjectEnterNode { + val enterNode = createAnonymousObjectEnterNode(anonymousObject) + // TODO: looks like there was some problem with enum initializers that causes `lastNodes` to be empty + lastNodes.popOrNull()?.let { addEdge(it, enterNode, preferredKind = EdgeKind.Forward) } + lastNodes.push(enterNode) + enterClass() + return enterNode + } + fun exitAnonymousObject(anonymousObject: FirAnonymousObject): Pair { val graph = exitClass(anonymousObject).also { currentGraph.addSubGraph(it) } - val node = createAnonymousObjectExitNode(anonymousObject).also { - // TODO: looks like there was some problem with enum initializers - if (lastNodes.isNotEmpty) { - addNewSimpleNode(it) - } + val enterNode = lastNodes.popOrNull() + if (enterNode !is AnonymousObjectEnterNode) { + throw AssertionError("anonymous object exit should be preceded by anonymous object enter, but got $enterNode") } - visitLocalClassFunctions(anonymousObject, node) - addEdge(node, graph.enterNode, preferredKind = EdgeKind.CfgForward) - return node to graph + val exitNode = createAnonymousObjectExitNode(anonymousObject) + // TODO: Intentionally not using anonymous object init blocks for data flow? Might've been a FE1.0 bug. + addEdge(enterNode, graph.enterNode, preferredKind = EdgeKind.CfgForward) + if (!graph.exitNode.isDead) { + addEdge(graph.exitNode, exitNode, preferredKind = EdgeKind.CfgForward) + } + addEdge(enterNode, exitNode, preferredKind = EdgeKind.DfgForward) + // TODO: Here we're assuming that the methods are called after the object is constructed, which is really not true + // (init blocks can call them). But FE1.0 did so too, hence the following code compiles and prints 0: + // val x: Int + // object { + // fun bar() = x + // init { x = bar() } + // } + // println(x) + visitLocalClassFunctions(anonymousObject, exitNode) + lastNodes.push(exitNode) + return exitNode to graph } fun exitAnonymousObjectExpression(anonymousObjectExpression: FirAnonymousObjectExpression): AnonymousObjectExpressionExitNode { @@ -474,7 +496,7 @@ class ControlFlowGraphBuilder { } } - fun visitLocalClassFunctions(klass: FirClass, node: CFGNodeWithCfgOwner<*>) { + private fun visitLocalClassFunctions(klass: FirClass, node: CFGNodeWithSubgraphs<*>) { klass.declarations.filterIsInstance().forEach { function -> val functionGraph = function.controlFlowGraphReference?.controlFlowGraph if (functionGraph != null && functionGraph.owner == null) { 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 6cc15f067a1..1cc435beeee 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 @@ -232,6 +232,9 @@ fun ControlFlowGraphBuilder.createPostponedLambdaEnterNode(fir: FirAnonymousFunc fun ControlFlowGraphBuilder.createAnonymousFunctionExpressionExitNode(fir: FirAnonymousFunctionExpression): AnonymousFunctionExpressionExitNode = AnonymousFunctionExpressionExitNode(currentGraph, fir, levelCounter, createId()) +fun ControlFlowGraphBuilder.createAnonymousObjectEnterNode(fir: FirAnonymousObject): AnonymousObjectEnterNode = + AnonymousObjectEnterNode(currentGraph, fir, levelCounter, createId()) + fun ControlFlowGraphBuilder.createAnonymousObjectExitNode(fir: FirAnonymousObject): AnonymousObjectExitNode = AnonymousObjectExitNode(currentGraph, fir, levelCounter, createId()) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraphRenderer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraphRenderer.kt index aef735688d4..bec3f8e48f3 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraphRenderer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraphRenderer.kt @@ -156,7 +156,7 @@ class FirControlFlowGraphRenderVisitor( renderEdges(kind) } - if (node is CFGNodeWithCfgOwner<*>) { + if (node is CFGNodeWithSubgraphs<*>) { val subNodes = node.subGraphs if (subNodes.isNotEmpty()) { print( diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt index fb22d3156cf..b4b52085112 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt @@ -484,7 +484,11 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor transformer.firProviderInterceptor ) } - dataFlowAnalyzer.enterClass() + if (!implicitTypeOnly && anonymousObject.controlFlowGraphReference == null) { + dataFlowAnalyzer.enterAnonymousObject(anonymousObject) + } else { + dataFlowAnalyzer.enterClass() + } val result = context.withAnonymousObject(anonymousObject, components) { transformDeclarationContent(anonymousObject, data) as FirAnonymousObject } 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 8965e53d9c3..3d883a70ebb 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 @@ -156,15 +156,21 @@ interface ExitNodeMarker // ----------------------------------- EnterNode for declaration with CFG ----------------------------------- -sealed class CFGNodeWithCfgOwner(owner: ControlFlowGraph, level: Int, id: Int) : CFGNode(owner, level, id) { +sealed class CFGNodeWithSubgraphs(owner: ControlFlowGraph, level: Int, id: Int) : CFGNode(owner, level, id) { private val _subGraphs = mutableListOf() fun addSubGraph(graph: ControlFlowGraph){ _subGraphs += graph } - val subGraphs: List by lazy { - _subGraphs.also { it.addIfNotNull(fir.controlFlowGraphReference?.controlFlowGraph) } + open val subGraphs: List + get() = _subGraphs +} + +sealed class CFGNodeWithCfgOwner(owner: ControlFlowGraph, level: Int, id: Int) : CFGNodeWithSubgraphs(owner, level, id) { + override val subGraphs: List by lazy { + fir.controlFlowGraphReference?.controlFlowGraph?.run(::addSubGraph) + super.subGraphs } } @@ -271,7 +277,13 @@ class LocalClassExitNode(owner: ControlFlowGraph, override val fir: FirRegularCl } } -class AnonymousObjectExitNode(owner: ControlFlowGraph, override val fir: FirAnonymousObject, level: Int, id: Int) : CFGNodeWithCfgOwner(owner, level, id) { +class AnonymousObjectEnterNode(owner: ControlFlowGraph, override val fir: FirAnonymousObject, level: Int, id: Int) : CFGNodeWithCfgOwner(owner, level, id) { + override fun accept(visitor: ControlFlowGraphVisitor, data: D): R { + return visitor.visitAnonymousObjectEnterNode(this, data) + } +} + +class AnonymousObjectExitNode(owner: ControlFlowGraph, override val fir: FirAnonymousObject, level: Int, id: Int) : CFGNodeWithSubgraphs(owner, level, id) { override fun accept(visitor: ControlFlowGraphVisitor, data: D): R { return visitor.visitAnonymousObjectExitNode(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 504c155fd2f..d2c23ac258b 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 @@ -111,6 +111,7 @@ fun CFGNode<*>.render(): String = is ClassEnterNode -> "Enter class ${owner.name}" 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" 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 0ccfe858b77..6be5369ff50 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 @@ -52,6 +52,10 @@ abstract class ControlFlowGraphVisitor { // ----------------------------------- Classes ----------------------------------- + open fun visitAnonymousObjectEnterNode(node: AnonymousObjectEnterNode, data: D): R { + return visitNode(node, data) + } + open fun visitAnonymousObjectExitNode(node: AnonymousObjectExitNode, data: D): R { return visitNode(node, data) } diff --git a/compiler/testData/diagnostics/tests/controlFlowAnalysis/initializationInLocalClass.fir.kt b/compiler/testData/diagnostics/tests/controlFlowAnalysis/initializationInLocalClass.fir.kt index ff3640e8e12..7eb67a08aba 100644 --- a/compiler/testData/diagnostics/tests/controlFlowAnalysis/initializationInLocalClass.fir.kt +++ b/compiler/testData/diagnostics/tests/controlFlowAnalysis/initializationInLocalClass.fir.kt @@ -19,7 +19,7 @@ fun bar() { } } // Ok - x.length + x.length } fun gav() { @@ -53,7 +53,7 @@ fun gau() { } } // Ok - x.length + x.length val y: String fun local() { object: Any() {