aadea0e26f
Interpretation: a graph A is a subgraph of B if information available at nodes of A depends on the paths taken in B. For example, local classes are subgraphs of a graph in which they are declared, and members of those classes are subgraphs of the local class itself - because these members can reference captured values. Consequences: * if graph G is a subgraph of node N, then G is a subgraph of N's owner; * `ControlFlowAnalysisDiagnosticComponent` will only visit root graphs; * `graph.traverse` will ignore subgraph boundaries, as if all subgraphs are inlined into one huge root graph; * if a control flow checker needs information from a declaration to which a graph is attached, it must look at subgraphs explicitly. For example, consider the `callsInPlace` checker. When a function has a `callsInPlace` contract and a local declaration, the checker must visit that local declaration to ensure it does not capture the allegedly called-in-place argument - hence `graph.traverse` will look at the nodes. However, the local declaration can also be a function with its own `callsInPlace` contracts, so the checker should also run for it in isolation. If that sounds quadratic, that's because unfortunately it is.
249 lines
8.3 KiB
Plaintext
Vendored
249 lines
8.3 KiB
Plaintext
Vendored
digraph smartcastInByClause_kt {
|
|
graph [nodesep=3]
|
|
node [shape=box penwidth=2]
|
|
edge [penwidth=2]
|
|
|
|
subgraph cluster_0 {
|
|
color=red
|
|
0 [label="Enter function <init>" style="filled" fillcolor=red];
|
|
1 [label="Delegated constructor call: super<R|kotlin/Any|>()" style="filled" fillcolor=yellow];
|
|
2 [label="Exit function <init>" style="filled" fillcolor=red];
|
|
}
|
|
0 -> {1};
|
|
1 -> {2};
|
|
|
|
subgraph cluster_1 {
|
|
color=red
|
|
9 [label="Enter class A" style="filled" fillcolor=red];
|
|
10 [label="Part of class initialization"];
|
|
subgraph cluster_2 {
|
|
color=blue
|
|
3 [label="Enter property" style="filled" fillcolor=red];
|
|
4 [label="Access variable R|<local>/path|"];
|
|
5 [label="Exit property" style="filled" fillcolor=red];
|
|
}
|
|
11 [label="Part of class initialization"];
|
|
subgraph cluster_3 {
|
|
color=blue
|
|
6 [label="Enter property" style="filled" fillcolor=red];
|
|
7 [label="Access variable R|<local>/index|"];
|
|
8 [label="Exit property" style="filled" fillcolor=red];
|
|
}
|
|
12 [label="Exit class A" style="filled" fillcolor=red];
|
|
}
|
|
9 -> {10} [color=green];
|
|
10 -> {3} [color=green];
|
|
10 -> {11} [style=dotted];
|
|
10 -> {3} [style=dashed];
|
|
11 -> {6} [color=green];
|
|
11 -> {12} [style=dotted];
|
|
11 -> {6} [style=dashed];
|
|
3 -> {4};
|
|
4 -> {5};
|
|
5 -> {11} [color=green];
|
|
6 -> {7};
|
|
7 -> {8};
|
|
8 -> {12} [color=green];
|
|
|
|
subgraph cluster_4 {
|
|
color=red
|
|
13 [label="Enter class Base" style="filled" fillcolor=red];
|
|
14 [label="Exit class Base" style="filled" fillcolor=red];
|
|
}
|
|
13 -> {14} [color=green];
|
|
|
|
subgraph cluster_5 {
|
|
color=red
|
|
15 [label="Enter function <init>" style="filled" fillcolor=red];
|
|
16 [label="Delegated constructor call: super<R|kotlin/Any|>()" style="filled" fillcolor=yellow];
|
|
17 [label="Exit function <init>" style="filled" fillcolor=red];
|
|
}
|
|
15 -> {16};
|
|
16 -> {17};
|
|
|
|
subgraph cluster_6 {
|
|
color=red
|
|
21 [label="Enter class Derived" style="filled" fillcolor=red];
|
|
22 [label="Part of class initialization"];
|
|
subgraph cluster_7 {
|
|
color=blue
|
|
18 [label="Enter property" style="filled" fillcolor=red];
|
|
19 [label="Access variable R|<local>/index|"];
|
|
20 [label="Exit property" style="filled" fillcolor=red];
|
|
}
|
|
23 [label="Exit class Derived" style="filled" fillcolor=red];
|
|
}
|
|
21 -> {22} [color=green];
|
|
22 -> {18} [color=green];
|
|
22 -> {23} [style=dotted];
|
|
22 -> {18} [style=dashed];
|
|
18 -> {19};
|
|
19 -> {20};
|
|
20 -> {23} [color=green];
|
|
|
|
subgraph cluster_8 {
|
|
color=red
|
|
24 [label="Enter function test" style="filled" fillcolor=red];
|
|
subgraph cluster_9 {
|
|
color=blue
|
|
25 [label="Enter block"];
|
|
26 [label="Access variable R|<local>/a|"];
|
|
27 [label="Enter safe call"];
|
|
28 [label="Access variable R|/A.path|"];
|
|
29 [label="Exit safe call"];
|
|
30 [label="Exit lhs of ?:"];
|
|
31 [label="Enter rhs of ?:"];
|
|
32 [label="Const: Null(null)"];
|
|
33 [label="Jump: ^test Null(null)"];
|
|
34 [label="Stub" style="filled" fillcolor=gray];
|
|
35 [label="Lhs of ?: is not null"];
|
|
36 [label="Exit ?:"];
|
|
37 [label="Variable declaration: lval path: R|kotlin/String|"];
|
|
38 [label="Access variable R|<local>/a|"];
|
|
39 [label="Smart cast: R|<local>/a|"];
|
|
40 [label="Access variable R|/A.index|"];
|
|
41 [label="Function call: R|/takeInt|(...)" style="filled" fillcolor=yellow];
|
|
42 [label="Enter anonymous object"];
|
|
subgraph cluster_10 {
|
|
color=blue
|
|
49 [label="Enter class <anonymous object>" style="filled" fillcolor=red];
|
|
50 [label="Part of class initialization"];
|
|
subgraph cluster_11 {
|
|
color=blue
|
|
53 [label="Enter field" style="filled" fillcolor=red];
|
|
54 [label="Access variable R|<local>/a|"];
|
|
55 [label="Smart cast: R|<local>/a|"];
|
|
56 [label="Access variable R|/A.index|"];
|
|
57 [label="Function call: R|/Derived.Derived|(...)" style="filled" fillcolor=yellow];
|
|
58 [label="Exit field" style="filled" fillcolor=red];
|
|
}
|
|
51 [label="Part of class initialization"];
|
|
subgraph cluster_12 {
|
|
color=blue
|
|
59 [label="Enter property" style="filled" fillcolor=red];
|
|
60 [label="Access variable R|<local>/a|"];
|
|
61 [label="Smart cast: R|<local>/a|"];
|
|
62 [label="Access variable R|/A.index|"];
|
|
63 [label="Exit property" style="filled" fillcolor=red];
|
|
}
|
|
52 [label="Exit class <anonymous object>" style="filled" fillcolor=red];
|
|
}
|
|
43 [label="Exit anonymous object"];
|
|
44 [label="Exit anonymous object expression"];
|
|
45 [label="Jump: ^test object : R|Base| {
|
|
private constructor(): R|<anonymous>| {
|
|
super<R|kotlin/Any|>()
|
|
}
|
|
|
|
private final field $$delegate_0: R|Base| = R|/Derived.Derived|(R|<local>/a|.R|/A.index|)
|
|
|
|
public final val x: R|kotlin/Int| = R|<local>/a|.R|/A.index|
|
|
public get(): R|kotlin/Int|
|
|
|
|
public final fun foo(): R|kotlin/Unit| {
|
|
R|/takeInt|(R|<local>/a|.R|/A.index|)
|
|
}
|
|
|
|
}
|
|
"];
|
|
46 [label="Stub" style="filled" fillcolor=gray];
|
|
47 [label="Exit block" style="filled" fillcolor=gray];
|
|
}
|
|
48 [label="Exit function test" style="filled" fillcolor=red];
|
|
}
|
|
subgraph cluster_13 {
|
|
color=blue
|
|
67 [label="Enter function foo" style="filled" fillcolor=red];
|
|
subgraph cluster_14 {
|
|
color=blue
|
|
68 [label="Enter block"];
|
|
69 [label="Access variable R|<local>/a|"];
|
|
70 [label="Smart cast: R|<local>/a|"];
|
|
71 [label="Access variable R|/A.index|"];
|
|
72 [label="Function call: R|/takeInt|(...)" style="filled" fillcolor=yellow];
|
|
73 [label="Exit block"];
|
|
}
|
|
74 [label="Exit function foo" style="filled" fillcolor=red];
|
|
}
|
|
subgraph cluster_15 {
|
|
color=blue
|
|
64 [label="Enter function <init>" style="filled" fillcolor=red];
|
|
65 [label="Delegated constructor call: super<R|kotlin/Any|>()" style="filled" fillcolor=yellow];
|
|
66 [label="Exit function <init>" style="filled" fillcolor=red];
|
|
}
|
|
24 -> {25};
|
|
25 -> {26};
|
|
26 -> {27 31};
|
|
27 -> {28};
|
|
28 -> {29};
|
|
29 -> {30};
|
|
30 -> {31 35};
|
|
31 -> {32};
|
|
32 -> {33};
|
|
33 -> {48};
|
|
33 -> {34} [style=dotted];
|
|
34 -> {36} [style=dotted];
|
|
35 -> {36};
|
|
36 -> {37};
|
|
37 -> {38};
|
|
38 -> {39};
|
|
39 -> {40};
|
|
40 -> {41};
|
|
41 -> {42};
|
|
41 -> {53 59 64 67} [color=red];
|
|
42 -> {49} [color=green];
|
|
42 -> {43} [color=red];
|
|
42 -> {49} [style=dashed];
|
|
43 -> {44};
|
|
43 -> {64 67} [color=green];
|
|
43 -> {64 67} [style=dashed];
|
|
44 -> {45};
|
|
45 -> {48};
|
|
45 -> {46} [style=dotted];
|
|
46 -> {47} [style=dotted];
|
|
47 -> {48} [style=dotted];
|
|
49 -> {50} [color=green];
|
|
50 -> {53} [color=green];
|
|
50 -> {51} [style=dotted];
|
|
50 -> {53} [style=dashed];
|
|
51 -> {59} [color=green];
|
|
51 -> {52} [style=dotted];
|
|
51 -> {59} [style=dashed];
|
|
52 -> {43} [color=green];
|
|
53 -> {54};
|
|
54 -> {55};
|
|
55 -> {56};
|
|
56 -> {57};
|
|
57 -> {58};
|
|
58 -> {51} [color=green];
|
|
59 -> {60};
|
|
60 -> {61};
|
|
61 -> {62};
|
|
62 -> {63};
|
|
63 -> {52} [color=green];
|
|
64 -> {65};
|
|
65 -> {66};
|
|
67 -> {68};
|
|
68 -> {69};
|
|
69 -> {70};
|
|
70 -> {71};
|
|
71 -> {72};
|
|
72 -> {73};
|
|
73 -> {74};
|
|
|
|
subgraph cluster_16 {
|
|
color=red
|
|
75 [label="Enter function takeInt" style="filled" fillcolor=red];
|
|
subgraph cluster_17 {
|
|
color=blue
|
|
76 [label="Enter block"];
|
|
77 [label="Exit block"];
|
|
}
|
|
78 [label="Exit function takeInt" style="filled" fillcolor=red];
|
|
}
|
|
75 -> {76};
|
|
76 -> {77};
|
|
77 -> {78};
|
|
|
|
}
|