@eagleoutice/flowr 2.9.7 → 2.9.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +21 -21
- package/abstract-interpretation/absint-visitor.d.ts +5 -4
- package/abstract-interpretation/absint-visitor.js +12 -11
- package/control-flow/basic-cfg-guided-visitor.d.ts +3 -3
- package/control-flow/basic-cfg-guided-visitor.js +7 -6
- package/control-flow/cfg-dead-code.js +12 -9
- package/control-flow/cfg-properties.d.ts +2 -2
- package/control-flow/cfg-properties.js +3 -2
- package/control-flow/cfg-to-basic-blocks.js +9 -12
- package/control-flow/control-flow-graph.d.ts +382 -78
- package/control-flow/control-flow-graph.js +591 -106
- package/control-flow/dfg-cfg-guided-visitor.d.ts +4 -4
- package/control-flow/dfg-cfg-guided-visitor.js +3 -3
- package/control-flow/diff-cfg.js +35 -29
- package/control-flow/extract-cfg.d.ts +3 -3
- package/control-flow/extract-cfg.js +145 -125
- package/control-flow/happens-before.js +2 -1
- package/control-flow/semantic-cfg-guided-visitor.js +2 -1
- package/control-flow/simple-visitor.js +8 -6
- package/control-flow/syntax-cfg-guided-visitor.js +2 -1
- package/control-flow/useless-loop.js +2 -1
- package/documentation/wiki-cfg.js +21 -9
- package/documentation/wiki-mk/doc-maker.js +1 -1
- package/package.json +1 -1
- package/project/context/flowr-file.d.ts +5 -0
- package/project/context/flowr-file.js +7 -0
- package/project/plugins/file-plugins/files/flowr-description-file.d.ts +1 -0
- package/project/plugins/file-plugins/files/flowr-description-file.js +5 -0
- package/project/plugins/file-plugins/files/flowr-namespace-file.d.ts +4 -0
- package/project/plugins/file-plugins/files/flowr-namespace-file.js +8 -0
- package/project/plugins/file-plugins/files/flowr-news-file.d.ts +4 -0
- package/project/plugins/file-plugins/files/flowr-news-file.js +8 -0
- package/queries/catalog/control-flow-query/control-flow-query-format.js +1 -1
- package/r-bridge/lang-4.x/tree-sitter/tree-sitter-normalize.d.ts +2 -1
- package/r-bridge/lang-4.x/tree-sitter/tree-sitter-normalize.js +19 -19
- package/search/search-executor/search-generators.js +2 -2
- package/util/assert.d.ts +3 -3
- package/util/mermaid/cfg.d.ts +1 -7
- package/util/mermaid/cfg.js +37 -44
- package/util/version.js +1 -1
|
@@ -1,15 +1,31 @@
|
|
|
1
1
|
import type { NodeId } from '../r-bridge/lang-4.x/ast/model/processing/node-id';
|
|
2
2
|
import type { MergeableRecord } from '../util/objects';
|
|
3
|
-
import
|
|
3
|
+
import { RFalse, RTrue } from '../r-bridge/lang-4.x/convert-values';
|
|
4
|
+
/**
|
|
5
|
+
* The type of a vertex in the {@link ControlFlowGraph}.
|
|
6
|
+
* Please use the helper object (e.g. {@link CfgVertex#getType|getType()}) to work with vertices instead of directly accessing the properties.
|
|
7
|
+
*/
|
|
4
8
|
export declare enum CfgVertexType {
|
|
5
|
-
/**
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
9
|
+
/**
|
|
10
|
+
* The explicit exit-nodes to ensure the hammock property.
|
|
11
|
+
* @see {@link CfgVertex.makeMarker|CfgVertex.makeMarker()} - for a helper function to create end marker vertices
|
|
12
|
+
*/
|
|
13
|
+
Marker = 0,
|
|
14
|
+
/**
|
|
15
|
+
* something like an if, assignment, ... even though in the classical sense of R they are still expressions
|
|
16
|
+
* @see {@link CfgVertex.makeStatement|CfgVertex.makeStatement()} - for a helper function to create statement vertices
|
|
17
|
+
*/
|
|
18
|
+
Statement = 1,
|
|
19
|
+
/**
|
|
20
|
+
* something like an addition, ...
|
|
21
|
+
* @see {@link CfgVertex.makeExpression|CfgVertex.makeExpression()} - for a helper function to create expression vertices
|
|
22
|
+
*/
|
|
23
|
+
Expression = 2,
|
|
24
|
+
/**
|
|
25
|
+
* a (as far as R allows this) 'basic' block
|
|
26
|
+
* @see {@link CfgVertex.makeBlock|CfgVertex.makeBlock()} - for a helper function to create basic block vertices
|
|
27
|
+
*/
|
|
28
|
+
Block = 3
|
|
13
29
|
}
|
|
14
30
|
export declare const enum CfgEdgeType {
|
|
15
31
|
/** a flow dependency */
|
|
@@ -18,75 +34,362 @@ export declare const enum CfgEdgeType {
|
|
|
18
34
|
Cd = 1
|
|
19
35
|
}
|
|
20
36
|
/**
|
|
21
|
-
*
|
|
37
|
+
* A vertex in the {@link ControlFlowGraph} that may have markers attached to it (e.g., for function calls).
|
|
38
|
+
* - `type`: the type of the vertex, either a statement or an expression
|
|
39
|
+
* - `id`: the id of the vertex, which should directly relate to the AST node
|
|
40
|
+
* - `children`: child nodes attached to this one
|
|
41
|
+
* - `callTargets`: if the vertex calls a function, this links all targets of this call
|
|
22
42
|
*/
|
|
23
|
-
|
|
43
|
+
type CfgBaseVertexWithMarker = [type: CfgVertexType, id: NodeId, mid?: NodeId[], end?: NodeId[], children?: NodeId[], callTargets?: Set<NodeId>];
|
|
24
44
|
/**
|
|
25
|
-
*
|
|
26
|
-
* Please use {@link CfgSimpleVertex} to refer to all potential vertex types within the graph.
|
|
45
|
+
* @see {@link CfgBaseVertexWithMarker}
|
|
27
46
|
*/
|
|
28
|
-
|
|
29
|
-
/** the type of the vertex */
|
|
30
|
-
type: CfgVertexType;
|
|
31
|
-
/** the id of the vertex, for non-blocks this should directly relate to the AST node */
|
|
32
|
-
id: NodeId;
|
|
33
|
-
/** child nodes attached to this one */
|
|
34
|
-
children?: NodeId[];
|
|
35
|
-
/** if the vertex calls a function, this links all targets of this call */
|
|
36
|
-
callTargets?: Set<NodeId>;
|
|
37
|
-
}
|
|
38
|
-
interface CfgWithMarker extends CfgBaseVertex {
|
|
39
|
-
/** mid-markers linked to this statement */
|
|
40
|
-
mid?: NodeId[];
|
|
41
|
-
/** end-markers linked to this statement */
|
|
42
|
-
end?: NodeId[];
|
|
43
|
-
}
|
|
44
|
-
export interface CfgStatementVertex extends CfgWithMarker {
|
|
45
|
-
type: CfgVertexType.Statement;
|
|
46
|
-
}
|
|
47
|
-
export interface CfgExpressionVertex extends CfgWithMarker {
|
|
48
|
-
type: CfgVertexType.Expression;
|
|
49
|
-
}
|
|
50
|
-
export interface CfgWithRoot extends CfgBaseVertex {
|
|
51
|
-
/** the vertex for which this is a marker */
|
|
52
|
-
root: NodeId;
|
|
53
|
-
}
|
|
54
|
-
export interface CfgEndMarkerVertex extends CfgWithRoot {
|
|
55
|
-
type: CfgVertexType.EndMarker;
|
|
56
|
-
}
|
|
57
|
-
export interface CfgBasicBlockVertex extends CfgBaseVertex {
|
|
58
|
-
type: CfgVertexType.Block;
|
|
59
|
-
/** The vertices that are part of this block, only connected by FDs, vertices should never occur in multiple bbs */
|
|
60
|
-
elems: readonly Exclude<CfgSimpleVertex, CfgBasicBlockVertex>[];
|
|
61
|
-
}
|
|
47
|
+
export type CfgStatementVertex = [CfgVertexType.Statement, ...a: unknown[]] & CfgBaseVertexWithMarker;
|
|
62
48
|
/**
|
|
63
|
-
*
|
|
49
|
+
* @see {@link CfgBaseVertexWithMarker}
|
|
64
50
|
*/
|
|
65
|
-
export type
|
|
51
|
+
export type CfgExpressionVertex = [CfgVertexType.Expression, ...a: unknown[]] & CfgBaseVertexWithMarker;
|
|
66
52
|
/**
|
|
67
|
-
*
|
|
53
|
+
* The root id is only stored if it is not derivable from the canonical id
|
|
54
|
+
* @see {@link CfgBaseVertexWithMarker}
|
|
68
55
|
*/
|
|
69
|
-
export
|
|
56
|
+
export type CfgMarkerVertex = NodeId | [CfgVertexType.Marker, ...a: unknown[]] & [type: CfgVertexType, id: NodeId, rootId?: NodeId];
|
|
70
57
|
/**
|
|
71
|
-
*
|
|
72
|
-
*
|
|
58
|
+
* A basic block vertex in the {@link ControlFlowGraph}.
|
|
59
|
+
* Contains the vertices that are part of this block, only connected by FDs, vertices should never occur in multiple bbs.
|
|
73
60
|
*/
|
|
74
|
-
export
|
|
61
|
+
export type CfgBasicBlockVertex = [CfgVertexType.Block, ...a: unknown[]] & [type: CfgVertexType, id: NodeId, elems: readonly Exclude<CfgVertex, CfgBasicBlockVertex>[]];
|
|
75
62
|
/**
|
|
76
|
-
*
|
|
63
|
+
* A vertex in the {@link ControlFlowGraph}.
|
|
64
|
+
* Please use the helper object (e.g. {@link CfgVertex#getType|getType()}) to work with vertices instead of directly accessing the properties.
|
|
65
|
+
*/
|
|
66
|
+
export type CfgVertex = CfgStatementVertex | CfgExpressionVertex | CfgBasicBlockVertex | CfgMarkerVertex;
|
|
67
|
+
/**
|
|
68
|
+
* Helper object for {@link CfgVertex} - a vertex in the {@link ControlFlowGraph} that may have markers attached to it (e.g., for function calls).
|
|
69
|
+
*/
|
|
70
|
+
export declare const CfgVertex: {
|
|
71
|
+
/**
|
|
72
|
+
* Create a new expression vertex with the given id, children, call targets, and markers.
|
|
73
|
+
* @param id - the id of the vertex, which should directly relate to the AST node
|
|
74
|
+
* @param children - child nodes attached to this one
|
|
75
|
+
* @param callTargets - if the vertex calls a function, this links all targets of this call
|
|
76
|
+
* @param mid - the ids of the mid-markers attached to this vertex, which should directly relate to the AST nodes of the mid markers
|
|
77
|
+
* @param end - the ids of the end-markers attached to this vertex, which should directly relate to the AST nodes of the end markers
|
|
78
|
+
* @see {@link CfgVertex#isExpression|isExpression()} - for a way to check whether a vertex is an expression vertex
|
|
79
|
+
*/
|
|
80
|
+
readonly makeExpression: (this: void, id: NodeId, { children, mid, end, callTargets }?: {
|
|
81
|
+
children?: NodeId[];
|
|
82
|
+
callTargets?: Set<NodeId>;
|
|
83
|
+
mid?: NodeId[];
|
|
84
|
+
end?: NodeId[];
|
|
85
|
+
}) => CfgExpressionVertex;
|
|
86
|
+
/**
|
|
87
|
+
* A convenience function to create a new expression vertex with a canonical end marker ({@link CfgVertex#toExitId|toExitId()}) based on the given id and the given id as root id for the end marker.
|
|
88
|
+
* @param id - the id of the vertex, which should directly relate to the AST node
|
|
89
|
+
* @param children - child nodes attached to this one
|
|
90
|
+
* @param callTargets - if the vertex calls a function, this links all targets of this call
|
|
91
|
+
* @param mid - the ids of the mid-markers attached to this vertex, which should directly relate to the AST nodes of the mid markers
|
|
92
|
+
* @see {@link CfgVertex#makeExpression|makeExpression()} - for a way to create expression vertices with a custom end marker
|
|
93
|
+
* @see {@link CfgVertex#makeExitMarker|makeExitMarker()} - for a helper function to create end marker vertices with a canonical id#
|
|
94
|
+
* @see {@link CfgVertex#toExitId|toExitId()} - for a way to convert the given id to a canonical end marker id
|
|
95
|
+
*/
|
|
96
|
+
readonly makeExpressionWithEnd: (this: void, id: NodeId, { children, mid, callTargets }?: {
|
|
97
|
+
children?: NodeId[];
|
|
98
|
+
callTargets?: Set<NodeId>;
|
|
99
|
+
mid?: NodeId[];
|
|
100
|
+
}) => CfgExpressionVertex;
|
|
101
|
+
/**
|
|
102
|
+
* A convenience function to create a new statement vertex with a canonical end marker ({@link CfgVertex#toExitId|toExitId()}) based on the given id and the given id as root id for the end marker.
|
|
103
|
+
* @param id - the id of the vertex, which should directly relate to the AST node
|
|
104
|
+
* @param children - child nodes attached to this one
|
|
105
|
+
* @param callTargets - if the vertex calls a function, this links all targets of this call
|
|
106
|
+
* @param mid - the ids of the mid-markers attached to this vertex, which should directly relate to the AST nodes of the mid markers
|
|
107
|
+
* @see {@link CfgVertex#makeExpression|makeExpression()} - for a way to create expression vertices with a custom end marker
|
|
108
|
+
* @see {@link CfgVertex#makeExitMarker|makeExitMarker()} - for a helper function to create end marker vertices with a canonical id#
|
|
109
|
+
* @see {@link CfgVertex#toExitId|toExitId()} - for a way to convert the given id to a canonical end marker id
|
|
110
|
+
*/
|
|
111
|
+
readonly makeStatementWithEnd: (this: void, id: NodeId, { children, mid, callTargets }?: {
|
|
112
|
+
children?: NodeId[];
|
|
113
|
+
callTargets?: Set<NodeId>;
|
|
114
|
+
mid?: NodeId[];
|
|
115
|
+
}) => CfgStatementVertex;
|
|
116
|
+
/**
|
|
117
|
+
* Create a new statement vertex with the given id, children, call targets, and markers.
|
|
118
|
+
* @param id - the id of the vertex, which should directly relate to the AST node
|
|
119
|
+
* @param children - child nodes attached to this one
|
|
120
|
+
* @param callTargets - if the vertex calls a function, this links all targets of this call
|
|
121
|
+
* @param mid - the ids of the mid-markers attached to this vertex, which should directly relate to the AST nodes of the mid markers
|
|
122
|
+
* @param end - the ids of the end-markers attached to this vertex, which should directly relate to the AST nodes of the end markers
|
|
123
|
+
* @see {@link CfgVertex#isStatement|isStatement()} - for a way to check whether a vertex is a statement vertex
|
|
124
|
+
*/
|
|
125
|
+
readonly makeStatement: (this: void, id: NodeId, { children, mid, end, callTargets }?: {
|
|
126
|
+
children?: NodeId[];
|
|
127
|
+
callTargets?: Set<NodeId>;
|
|
128
|
+
mid?: NodeId[];
|
|
129
|
+
end?: NodeId[];
|
|
130
|
+
}) => CfgStatementVertex;
|
|
131
|
+
/**
|
|
132
|
+
* A convenience function to create a new vertex which is either a statement or an expression.
|
|
133
|
+
*/
|
|
134
|
+
readonly makeExprOrStm: (this: void, id: NodeId, type: CfgVertexType.Expression | CfgVertexType.Statement, { children, mid, end, callTargets }?: {
|
|
135
|
+
children?: NodeId[];
|
|
136
|
+
callTargets?: Set<NodeId>;
|
|
137
|
+
mid?: NodeId[];
|
|
138
|
+
end?: NodeId[];
|
|
139
|
+
}) => CfgExpressionVertex | CfgStatementVertex;
|
|
140
|
+
/**
|
|
141
|
+
* Create a new marker vertex with the given id, root id, children, and call targets.
|
|
142
|
+
* @param id - the id of the vertex, which should directly relate to the AST node
|
|
143
|
+
* @param rootId - the id of the AST node this end marker corresponds to
|
|
144
|
+
* @see {@link CfgVertex#isMarker|isMarker()} - for a way to check whether a vertex is an end marker vertex
|
|
145
|
+
* @see {@link CfgVertex#getRootId|getRootId()} - for a way to get the root id of an end marker vertex
|
|
146
|
+
* @see {@link CfgVertex#makeExitMarker|makeExitMarker()} - for a helper function to create end marker vertices with a canonical id
|
|
147
|
+
*/
|
|
148
|
+
readonly makeMarker: (this: void, id: NodeId, rootId: NodeId) => CfgMarkerVertex;
|
|
149
|
+
/**
|
|
150
|
+
* A convenience function to create a new marker vertex with a canonical id ({@link CfgVertex#toExitId|toExitId()}) based on the given id and the given id as root id.
|
|
151
|
+
* @see {@link CfgVertex#makeMarker|makeMarker()} - for a way to create end marker vertices with a custom id
|
|
152
|
+
*/
|
|
153
|
+
readonly makeExitMarker: (this: void, id: NodeId) => CfgMarkerVertex;
|
|
154
|
+
/**
|
|
155
|
+
* Create a new basic block vertex with the given id, elements, children, and call targets.
|
|
156
|
+
* @param id - the id of the vertex, which should directly relate to the AST node
|
|
157
|
+
* @param elems - the vertices that are part of this block, only connected by FDs, vertices should never occur in multiple bbs
|
|
158
|
+
* @see {@link CfgVertex#isBlock|isBlock()} - for a way to check whether a vertex is a basic block vertex
|
|
159
|
+
*/
|
|
160
|
+
readonly makeBlock: (this: void, id: NodeId, elems: readonly Exclude<CfgVertex, CfgBasicBlockVertex>[]) => CfgBasicBlockVertex;
|
|
161
|
+
/**
|
|
162
|
+
* Check whether the given vertex is an expression vertex.
|
|
163
|
+
* @see {@link CfgVertex#makeExpression|makeExpression()} - for a way to create expression vertices
|
|
164
|
+
* @see {@link CfgVertex#getType|getType()} - for a way to get the type of a vertex instead of checking against a given type
|
|
165
|
+
*/
|
|
166
|
+
readonly isExpression: (this: void, vertex: CfgVertex | undefined) => vertex is CfgExpressionVertex;
|
|
167
|
+
/**
|
|
168
|
+
* Check whether the given vertex is a statement vertex.
|
|
169
|
+
* @see {@link CfgVertex#makeStatement|makeStatement()} - for a way to create statement vertices
|
|
170
|
+
* @see {@link CfgVertex#getType|getType()} - for a way to get the type of a vertex instead of checking against a given type
|
|
171
|
+
*/
|
|
172
|
+
readonly isStatement: (this: void, vertex: CfgVertex | undefined) => vertex is CfgStatementVertex;
|
|
173
|
+
/**
|
|
174
|
+
* Check whether the given vertex is an end marker vertex.
|
|
175
|
+
* @see {@link CfgVertex#makeMarker|makeMarker()} - for a way to create end marker vertices
|
|
176
|
+
* @see {@link CfgVertex#getType|getType()} - for a way to get the type of a vertex instead of checking against a given type
|
|
177
|
+
*/
|
|
178
|
+
readonly isMarker: (this: void, vertex: CfgVertex | undefined) => vertex is CfgMarkerVertex;
|
|
179
|
+
/**
|
|
180
|
+
* Check whether the given vertex is a basic block vertex.
|
|
181
|
+
* @see {@link CfgVertex#makeBlock|makeBlock()} - for a way to create basic block vertices
|
|
182
|
+
* @see {@link CfgVertex#getType|getType()} - for a way to get the type of a vertex instead of checking against a given type
|
|
183
|
+
*/
|
|
184
|
+
readonly isBlock: (this: void, vertex: CfgVertex | undefined) => vertex is CfgBasicBlockVertex;
|
|
185
|
+
/**
|
|
186
|
+
* Get the type of the given vertex.
|
|
187
|
+
* @example
|
|
188
|
+
* ```ts
|
|
189
|
+
* const vertex: CfgVertex = CfgVertex.makeExpr('node-1')
|
|
190
|
+
* console.log(CfgVertex.getType(vertex)); // Output: CfgVertexType.Expression
|
|
191
|
+
* ```
|
|
192
|
+
* @see {@link CfgVertex#isExpression|isExpression()}, {@link CfgVertex#isStatement|isStatement()}, {@link CfgVertex#isMarker|isMarker()}, {@link CfgVertex#isBlock|isBlock()} - for ways to check the type of a vertex against a specific type instead of getting the type and checking it against a specific type
|
|
193
|
+
* @see {@link CfgVertex#getId|getId()} - for a way to get the id of a vertex
|
|
194
|
+
* @see {@link CfgVertex#typeToString|typeToString()} - for a way to convert the type of a vertex to a string for easier debugging and visualization
|
|
195
|
+
*/
|
|
196
|
+
readonly getType: (this: void, vertex: CfgVertex) => CfgVertexType;
|
|
197
|
+
/**
|
|
198
|
+
* Convert the given vertex type to a string for easier debugging and visualization.
|
|
199
|
+
* @see {@link CfgVertexType} - for the possible vertex types
|
|
200
|
+
* @see {@link CfgVertex#getType|getType()} - for a way to get the type of a vertex and convert it to a string
|
|
201
|
+
*/
|
|
202
|
+
readonly typeToString: (this: void, type: CfgVertexType) => string;
|
|
203
|
+
/**
|
|
204
|
+
* Get the id of the given vertex, which should directly relate to the AST node.
|
|
205
|
+
* @example
|
|
206
|
+
* ```ts
|
|
207
|
+
* const vertex: CfgVertex = CfgVertex.makeExpr('node-1')
|
|
208
|
+
* console.log(CfgVertex.getId(vertex)); // Output: 'node-1'
|
|
209
|
+
* ```
|
|
210
|
+
* @see {@link CfgVertex#getType|getType()} - for a way to get the type of a vertex
|
|
211
|
+
* @see {@link CfgVertex#getRootId|getRootId()} - for a way to get the root id of a vertex
|
|
212
|
+
*/
|
|
213
|
+
readonly getId: <T extends CfgVertex | undefined>(this: void, vertex: T) => T extends undefined ? NodeId | undefined : NodeId;
|
|
214
|
+
/**
|
|
215
|
+
* Check whether two vertices are equal, i.e., they have the same type, id, and if they are basic block vertices, they also have the same elements in the same order.
|
|
216
|
+
*/
|
|
217
|
+
readonly equal: (this: void, a: CfgVertex, b: CfgVertex) => boolean;
|
|
218
|
+
/**
|
|
219
|
+
* Get the root id of a vertex, i.e., the id of the AST node it corresponds to.
|
|
220
|
+
* For normal vertices, this is the same as the id of the vertex itself, for end marker vertices, this is the root id stored in the vertex.
|
|
221
|
+
* @see {@link CfgVertex#unpackRoot|unpackRoot()} - for a way to unpack the root id of a marker vertex
|
|
222
|
+
*/
|
|
223
|
+
readonly getRootId: (this: void, vertex: CfgVertex) => NodeId;
|
|
224
|
+
/**
|
|
225
|
+
* Unpack the root id of a marker vertex, i.e., get the root id stored in the vertex or derive it from the canonical id if it is not explicitly stored.
|
|
226
|
+
* @see {@link CfgVertex#getRootId|getRootId()} - for a way to get the root id of a vertex, which uses this function for marker vertices
|
|
227
|
+
*/
|
|
228
|
+
readonly unpackRootId: (this: void, vertex: CfgMarkerVertex) => NodeId;
|
|
229
|
+
/**
|
|
230
|
+
* Get the elements of a basic block vertex, i.e., the vertices that are part of this block, only connected by FDs, vertices should never occur in multiple bbs.
|
|
231
|
+
* @see {@link CfgVertex#isBlock|isBlock()} - for a way to check whether a vertex is a basic block vertex before trying to get the elements
|
|
232
|
+
* @see {@link CfgVertex#setBasicBlockElements|setBasicBlockElements()} - for a way to set the elements of a basic block vertex
|
|
233
|
+
*/
|
|
234
|
+
readonly getBasicBlockElements: (this: void, vertex: CfgBasicBlockVertex) => readonly Exclude<CfgVertex, CfgBasicBlockVertex>[];
|
|
235
|
+
/**
|
|
236
|
+
* **Sets in-place**
|
|
237
|
+
* Set the elements of a basic block vertex, i.e., the vertices that are part of this block, only connected by FDs, vertices should never occur in multiple bbs.
|
|
238
|
+
* @see {@link CfgVertex#isBlock|isBlock()} - for a way to check whether a vertex is a basic block vertex before trying to set the elements
|
|
239
|
+
* @see {@link CfgVertex#getBasicBlockElements|getBasicBlockElements()} - for a way to get the elements of a basic block vertex
|
|
240
|
+
*/
|
|
241
|
+
readonly setBasicBlockElements: (this: void, vertex: CfgBasicBlockVertex, elems: readonly Exclude<CfgVertex, CfgBasicBlockVertex>[]) => void;
|
|
242
|
+
/**
|
|
243
|
+
* Get the ids of the mid-markers attached to this vertex, which should directly relate to the AST nodes of the mid markers.
|
|
244
|
+
* @see {@link CfgVertex#getMid|getMid()} - for a way to get the ids of the mid-markers attached to this vertex
|
|
245
|
+
* @see {@link CfgVertex#setEnd|setEnd()} - for a way to set the ids of the end-markers attached to this vertex
|
|
246
|
+
*/
|
|
247
|
+
readonly getEnd: (this: void, vertex: CfgVertex | undefined) => NodeId[] | undefined;
|
|
248
|
+
/**
|
|
249
|
+
* **Sets in-place**
|
|
250
|
+
* Set the ids of the end-markers attached to this vertex, which should directly relate to the AST nodes of the end markers.
|
|
251
|
+
* @see {@link CfgVertex#getEnd|getEnd()} - for a way to get the ids of the end-markers attached to this vertex
|
|
252
|
+
*/
|
|
253
|
+
readonly setEnd: (this: void, vertex: CfgStatementVertex | CfgExpressionVertex, endMarkers: NodeId[] | undefined) => void;
|
|
254
|
+
/**
|
|
255
|
+
* Get the ids of the mid-markers attached to this vertex, which should directly relate to the AST nodes of the mid markers.
|
|
256
|
+
*/
|
|
257
|
+
readonly getMid: (this: void, vertex: CfgVertex) => NodeId[] | undefined;
|
|
258
|
+
/**
|
|
259
|
+
* **Sets in-place**
|
|
260
|
+
* Set the ids of the mid-markers attached to this vertex, which should directly relate to the AST nodes of the mid markers.
|
|
261
|
+
* @see {@link CfgVertex#getMid|getMid()} - for a way to get the ids of the mid-markers attached to this vertex
|
|
262
|
+
* @see {@link CfgVertex#setEnd|setEnd()} - for a way to set the ids of the end-markers attached to this vertex
|
|
263
|
+
*/
|
|
264
|
+
readonly setMid: (this: void, vertex: CfgStatementVertex | CfgExpressionVertex, midMarkers: NodeId[] | undefined) => void;
|
|
265
|
+
/**
|
|
266
|
+
* Converts the given id to a, canonical, basic block lift (i.e., it adds 'bb-' as a prefix).
|
|
267
|
+
*/
|
|
268
|
+
readonly toBasicBlockId: <Id extends NodeId>(this: void, id: Id) => `bb-${Id}`;
|
|
269
|
+
/**
|
|
270
|
+
* Converts the given id to a canonical, end marker lift (i.e., it adds '-end' as a suffix).
|
|
271
|
+
* @see {@link CfgVertex#fromExitId|fromExitId()} - for a way to convert the given id from a canonical end marker lift to the original id (i.e., it removes '-end' as a suffix if it is present)
|
|
272
|
+
*/
|
|
273
|
+
readonly toExitId: <Id extends NodeId>(this: void, id: Id) => `${Id}-e`;
|
|
274
|
+
/**
|
|
275
|
+
* Converts the given id from a canonical end marker lift to the original id (i.e., it removes '-end' as a suffix if it is present).
|
|
276
|
+
* @see {@link CfgVertex#toExitId|toExitId()} - for a way to convert the given id to a canonical end marker lift (i.e., it adds '-end' as a suffix)
|
|
277
|
+
*/
|
|
278
|
+
readonly fromExitId: (this: void, exitId: NodeId) => NodeId;
|
|
279
|
+
/**
|
|
280
|
+
* Get the call targets of a statement or expression vertex, which links all targets of this call.
|
|
281
|
+
*/
|
|
282
|
+
readonly getCallTargets: (this: void, vertex: CfgVertex | undefined) => Set<NodeId> | undefined;
|
|
283
|
+
/**
|
|
284
|
+
* **Sets in-place**
|
|
285
|
+
* Set the call targets of a statement or expression vertex, which links all targets of this call.
|
|
286
|
+
* @see {@link CfgVertex#getCallTargets|getCallTargets()} - for a way to get the call targets of a statement or expression vertex
|
|
287
|
+
* @see {@link CfgVertex#mapCallTargets|mapCallTargets()} - for a way to map the call targets of a statement or expression vertex to new call targets
|
|
288
|
+
*/
|
|
289
|
+
readonly setCallTargets: (this: void, vertex: CfgStatementVertex | CfgExpressionVertex, callTargets: Set<NodeId>) => void;
|
|
290
|
+
/**
|
|
291
|
+
* Map the call targets of a statement or expression vertex, which links all targets of this call, to new call targets using the given mapping function.
|
|
292
|
+
* @see {@link CfgVertex#getCallTargets|getCallTargets()} - for a way to get the call targets of a statement or expression vertex
|
|
293
|
+
* @see {@link CfgVertex#setCallTargets|setCallTargets()} - for a way to set the call targets of a statement or expression vertex to new call targets
|
|
294
|
+
*/
|
|
295
|
+
readonly mapCallTargets: (this: void, vertex: CfgStatementVertex | CfgExpressionVertex, mapFn: (targets: Set<NodeId> | undefined) => Set<NodeId>) => void;
|
|
296
|
+
/**
|
|
297
|
+
* Get the children of a statement or expression vertex, i.e., the child nodes attached to this one.
|
|
298
|
+
*/
|
|
299
|
+
readonly getChildren: (this: void, vertex: CfgVertex | undefined) => NodeId[] | undefined;
|
|
300
|
+
};
|
|
301
|
+
type CfgFlowDependencyEdge = CfgEdgeType.Fd;
|
|
302
|
+
type CfgControlDependencyEdge = [c: NodeId, w: typeof RTrue | typeof RFalse];
|
|
303
|
+
/**
|
|
304
|
+
* An edge in the {@link ControlFlowGraph}.
|
|
305
|
+
* @see {@link CfgEdge} - for helper functions to work with edges.
|
|
77
306
|
*/
|
|
78
|
-
export declare function getVertexRootId(vertex: CfgSimpleVertex): NodeId;
|
|
79
|
-
interface CfgFlowDependencyEdge extends MergeableRecord {
|
|
80
|
-
label: CfgEdgeType.Fd;
|
|
81
|
-
}
|
|
82
|
-
export interface CfgControlDependencyEdge extends MergeableRecord {
|
|
83
|
-
label: CfgEdgeType.Cd;
|
|
84
|
-
/** the id which caused the control dependency */
|
|
85
|
-
caused: NodeId;
|
|
86
|
-
/** is the control dependency satisfied with a true condition or is it negated (e.g., else-branch)? */
|
|
87
|
-
when: typeof RTrue | typeof RFalse;
|
|
88
|
-
}
|
|
89
307
|
export type CfgEdge = CfgFlowDependencyEdge | CfgControlDependencyEdge;
|
|
308
|
+
/**
|
|
309
|
+
* Helper object for {@link CfgEdge} - an edge in the {@link ControlFlowGraph}.
|
|
310
|
+
*/
|
|
311
|
+
export declare const CfgEdge: {
|
|
312
|
+
/**
|
|
313
|
+
* Check whether the given edge is a flow dependency edge.
|
|
314
|
+
*/
|
|
315
|
+
readonly isFlowDependency: (this: void, edge: CfgEdge | undefined) => edge is CfgFlowDependencyEdge;
|
|
316
|
+
/**
|
|
317
|
+
* Check whether the given edge is a control dependency edge.
|
|
318
|
+
*/
|
|
319
|
+
readonly isControlDependency: (this: void, edge: CfgEdge | undefined) => edge is CfgControlDependencyEdge;
|
|
320
|
+
/**
|
|
321
|
+
* Create a flow dependency edge.
|
|
322
|
+
*/
|
|
323
|
+
readonly makeFd: (this: void) => CfgFlowDependencyEdge;
|
|
324
|
+
/**
|
|
325
|
+
* Create a control dependency edge with the given cause and condition.
|
|
326
|
+
* @param controlId - the id of the vertex that causes the control dependency
|
|
327
|
+
* @param whenTrue - whether the control dependency is satisfied with a true condition or is it negated (e.g., else-branch)
|
|
328
|
+
* @see {@link CfgEdge#makeCdTrue|makeCdTrue()} - for a version of this function that assumes the control dependency is satisfied with a true condition
|
|
329
|
+
* @see {@link CfgEdge#makeCdFalse|makeCdFalse()} - for a version of this function that assumes the control dependency is negated (e.g., else-branch)
|
|
330
|
+
*/
|
|
331
|
+
readonly makeCd: (this: void, controlId: NodeId, whenTrue: typeof RTrue | typeof RFalse) => CfgControlDependencyEdge;
|
|
332
|
+
/**
|
|
333
|
+
* Create a control dependency edge with the given cause and a true condition.
|
|
334
|
+
* @param controlId - the id of the vertex that causes the control dependency
|
|
335
|
+
* @see {@link CfgEdge#makeCd|makeCd()} - for a version of this function that allows to specify the condition as well
|
|
336
|
+
*/
|
|
337
|
+
readonly makeCdTrue: (this: void, controlId: NodeId) => CfgControlDependencyEdge;
|
|
338
|
+
/**
|
|
339
|
+
* Create a control dependency edge with the given cause and a negated condition (e.g., else-branch).
|
|
340
|
+
* @param controlId - the id of the vertex that causes the control dependency
|
|
341
|
+
* @see {@link CfgEdge#makeCd|makeCd()} - for a version of this function that allows to specify the condition as well
|
|
342
|
+
*/
|
|
343
|
+
readonly makeCdFalse: (this: void, controlId: NodeId) => CfgControlDependencyEdge;
|
|
344
|
+
/**
|
|
345
|
+
* Get the cause of a control dependency edge, i.e., the id of the vertex that causes the control dependency.
|
|
346
|
+
* If the edge is not a control dependency edge, this returns undefined.
|
|
347
|
+
*
|
|
348
|
+
* This is the pendant of {@link CfgEdge#isControlDependency|isControlDependency()} on a {@link CfgEdge}.
|
|
349
|
+
* @see {@link CfgEdge#unpackCause|unpackCause()} - for a version of this function that assumes the edge is a control dependency edge and hence does not return undefined
|
|
350
|
+
*/
|
|
351
|
+
readonly getCause: (this: void, edge: CfgEdge) => NodeId | undefined;
|
|
352
|
+
/**
|
|
353
|
+
* Get the cause of a control dependency edge, i.e., the id of the vertex that causes the control dependency.
|
|
354
|
+
*/
|
|
355
|
+
readonly unpackCause: (this: void, edge: CfgControlDependencyEdge) => NodeId;
|
|
356
|
+
/**
|
|
357
|
+
* Get whether the control dependency edge is satisfied with a true condition or is it negated (e.g., else-branch).
|
|
358
|
+
* If the edge is not a control dependency edge, this returns undefined.
|
|
359
|
+
*
|
|
360
|
+
* This is the pendant of {@link CfgEdge#isControlDependency|isControlDependency()} on a {@link CfgEdge}.
|
|
361
|
+
* @see {@link CfgEdge#unpackWhen|unpackWhen()} - for a version of this function that assumes the edge is a control dependency edge and hence does not return undefined
|
|
362
|
+
*/
|
|
363
|
+
readonly getWhen: (this: void, edge: CfgEdge) => typeof RTrue | typeof RFalse | undefined;
|
|
364
|
+
/**
|
|
365
|
+
* Get whether the control dependency edge is satisfied with a true condition or is it negated (e.g., else-branch).
|
|
366
|
+
*/
|
|
367
|
+
readonly unpackWhen: (this: void, edge: CfgControlDependencyEdge) => typeof RTrue | typeof RFalse;
|
|
368
|
+
/**
|
|
369
|
+
* Check whether two edges are equal.
|
|
370
|
+
*/
|
|
371
|
+
readonly equals: (this: void, a: CfgEdge, b: CfgEdge) => boolean;
|
|
372
|
+
/**
|
|
373
|
+
* Check whether the given edge is of the given type.
|
|
374
|
+
* @see {@link CfgEdge#getType|getType()} - for a version of this function that returns the type of the edge instead of checking against a given type
|
|
375
|
+
*/
|
|
376
|
+
readonly isOfType: (this: void, edge: CfgEdge, type: CfgEdgeType) => boolean;
|
|
377
|
+
/**
|
|
378
|
+
* Get the type of the given edge.
|
|
379
|
+
* @see {@link CfgEdge#isOfType|isOfType()} - for a version of this function that checks whether the edge is of a given type
|
|
380
|
+
*/
|
|
381
|
+
readonly getType: (this: void, edge: CfgEdge) => CfgEdgeType;
|
|
382
|
+
/**
|
|
383
|
+
* Provide a string representation of the given edge, e.g., for debugging or visualization purposes.
|
|
384
|
+
* @see {@link CfgEdge#toString|toString()} - for a version of this function that also includes the details of the edge (e.g., cause and condition for control dependency edges)
|
|
385
|
+
*/
|
|
386
|
+
readonly typeToString: (this: void, edge: CfgEdge) => string;
|
|
387
|
+
/**
|
|
388
|
+
* Provide a string representation of the given edge, including its details (e.g., cause and condition for control dependency edges), e.g., for debugging or visualization purposes.
|
|
389
|
+
* @see {@link CfgEdge#typeToString|typeToString()} - for a version of this function that only includes the type of the edge
|
|
390
|
+
*/
|
|
391
|
+
readonly toString: (this: void, edge: CfgEdge) => string;
|
|
392
|
+
};
|
|
90
393
|
/**
|
|
91
394
|
* A read-only view of the {@link ControlFlowGraph}.
|
|
92
395
|
*/
|
|
@@ -108,7 +411,7 @@ export interface ReadOnlyControlFlowGraph {
|
|
|
108
411
|
* @see {@link ReadOnlyControlFlowGraph#getVertex|getVertex()} - for a way to get a specific vertex by its id.
|
|
109
412
|
* @see {@link ReadOnlyControlFlowGraph#edges|edges()} - for a way to get all edges in the graph.
|
|
110
413
|
*/
|
|
111
|
-
readonly vertices: (includeBasicBlockElements: boolean) => ReadonlyMap<NodeId,
|
|
414
|
+
readonly vertices: (includeBasicBlockElements: boolean) => ReadonlyMap<NodeId, CfgVertex>;
|
|
112
415
|
/**
|
|
113
416
|
* Get all edges in the graph, independent of their sources and targets.
|
|
114
417
|
* If you are only interested in the edges of a specific node, please use {@link ReadOnlyControlFlowGraph#outgoingEdges|outgoingEdges()} or {@link ReadOnlyControlFlowGraph#ingoingEdges|ingoingEdges()}.
|
|
@@ -137,7 +440,7 @@ export interface ReadOnlyControlFlowGraph {
|
|
|
137
440
|
*
|
|
138
441
|
* This is the pendant of {@link DataflowGraph#getVertex|getVertex()} on a {@link DataflowGraph}.
|
|
139
442
|
*/
|
|
140
|
-
readonly getVertex: (id: NodeId, includeBlocks?: boolean) =>
|
|
443
|
+
readonly getVertex: (id: NodeId, includeBlocks?: boolean) => CfgVertex | undefined;
|
|
141
444
|
/**
|
|
142
445
|
* Check if a vertex with the given id exists in the graph.
|
|
143
446
|
* @param id - the id of the vertex to check
|
|
@@ -158,7 +461,7 @@ export interface ReadOnlyControlFlowGraph {
|
|
|
158
461
|
}
|
|
159
462
|
/**
|
|
160
463
|
* This class represents the control flow graph of an R program.
|
|
161
|
-
* The control flow may be hierarchical when confronted with function definitions (see {@link
|
|
464
|
+
* The control flow may be hierarchical when confronted with function definitions (see {@link CfgVertex} and {@link CFG#rootVertexIds|rootVertexIds()}).
|
|
162
465
|
*
|
|
163
466
|
* There are two very simple visitors to traverse a CFG:
|
|
164
467
|
* - {@link visitCfgInOrder} visits the graph in the order of the vertices
|
|
@@ -166,18 +469,18 @@ export interface ReadOnlyControlFlowGraph {
|
|
|
166
469
|
*
|
|
167
470
|
* If you want to prohibit modification, please refer to the {@link ReadOnlyControlFlowGraph} interface.
|
|
168
471
|
*/
|
|
169
|
-
export declare class ControlFlowGraph<Vertex extends
|
|
170
|
-
private readonly
|
|
472
|
+
export declare class ControlFlowGraph<Vertex extends CfgVertex = CfgVertex> implements ReadOnlyControlFlowGraph {
|
|
473
|
+
private readonly roots;
|
|
171
474
|
/** Nesting-Independent vertex information, mapping the id to the vertex */
|
|
172
|
-
private readonly
|
|
475
|
+
private readonly vtxInfos;
|
|
173
476
|
/** the basic block children map contains a mapping of ids to all vertices that are nested in basic blocks, mapping them to the Id of the block they appear in */
|
|
174
477
|
private readonly bbChildren;
|
|
175
478
|
/** basic block agnostic edges */
|
|
176
|
-
private readonly
|
|
479
|
+
private readonly edgeInfos;
|
|
177
480
|
/** reverse edges for bidirectional mapping */
|
|
178
|
-
private readonly
|
|
481
|
+
private readonly revEdgeInfos;
|
|
179
482
|
/** used as an optimization to avoid unnecessary lookups */
|
|
180
|
-
private
|
|
483
|
+
private _mayBB;
|
|
181
484
|
/**
|
|
182
485
|
* Add a new vertex to the control flow graph.
|
|
183
486
|
* @see {@link ControlFlowGraph#addEdge|addEdge()} - to add an edge
|
|
@@ -196,13 +499,13 @@ export declare class ControlFlowGraph<Vertex extends CfgSimpleVertex = CfgSimple
|
|
|
196
499
|
outgoingEdges(node: NodeId): ReadonlyMap<NodeId, CfgEdge> | undefined;
|
|
197
500
|
ingoingEdges(node: NodeId): ReadonlyMap<NodeId, CfgEdge> | undefined;
|
|
198
501
|
rootIds(): ReadonlySet<NodeId>;
|
|
199
|
-
vertices(includeBasicBlockElements?: boolean): ReadonlyMap<NodeId,
|
|
502
|
+
vertices(includeBasicBlockElements?: boolean): ReadonlyMap<NodeId, CfgVertex>;
|
|
200
503
|
getBasicBlock(elemId: NodeId): CfgBasicBlockVertex | undefined;
|
|
201
504
|
edges(): ReadonlyMap<NodeId, ReadonlyMap<NodeId, CfgEdge>>;
|
|
202
505
|
/**
|
|
203
506
|
* Retrieve a vertex by its id.
|
|
204
507
|
*/
|
|
205
|
-
getVertex(id: NodeId, includeBlocks?: boolean):
|
|
508
|
+
getVertex(id: NodeId, includeBlocks?: boolean): CfgVertex | undefined;
|
|
206
509
|
hasVertex(id: NodeId, includeBlocks?: boolean): boolean;
|
|
207
510
|
mayHaveBasicBlocks(): boolean;
|
|
208
511
|
/**
|
|
@@ -221,6 +524,7 @@ export declare class ControlFlowGraph<Vertex extends CfgSimpleVertex = CfgSimple
|
|
|
221
524
|
/** merges b into a */
|
|
222
525
|
mergeTwoBasicBlocks(a: NodeId, b: NodeId): this;
|
|
223
526
|
/**
|
|
527
|
+
* **This Operation is in-place and modifies the current graph.**
|
|
224
528
|
* Merge another control flow graph into this one.
|
|
225
529
|
* @param other - the other control flow graph to merge into this one
|
|
226
530
|
* @param forceNested - should the other graph be assumed to be fully nested (e.g., within a function definition).
|
|
@@ -233,7 +537,7 @@ export declare class ControlFlowGraph<Vertex extends CfgSimpleVertex = CfgSimple
|
|
|
233
537
|
* Summarizes the control information of a program
|
|
234
538
|
* @see {@link emptyControlFlowInformation} - to create an empty control flow information object
|
|
235
539
|
*/
|
|
236
|
-
export interface ControlFlowInformation<Vertex extends
|
|
540
|
+
export interface ControlFlowInformation<Vertex extends CfgVertex = CfgVertex> extends MergeableRecord {
|
|
237
541
|
/** all active 'return'(-like) unconditional jumps */
|
|
238
542
|
returns: NodeId[];
|
|
239
543
|
/** all active 'break'(-like) unconditional jumps */
|