@eagleoutice/flowr 2.1.7 → 2.1.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 +2 -1
- package/abstract-interpretation/normalized-ast-fold.d.ts +124 -0
- package/abstract-interpretation/normalized-ast-fold.js +178 -0
- package/benchmark/summarizer/first-phase/process.js +6 -5
- package/cli/repl/commands/repl-dataflow.js +5 -2
- package/cli/repl/commands/repl-normalize.js +5 -2
- package/cli/repl/commands/repl-query.js +2 -2
- package/cli/repl/server/messages/message-query.js +1 -1
- package/cli/slicer-app.js +1 -1
- package/core/steps/pipeline/pipeline.d.ts +63 -0
- package/dataflow/environments/default-builtin-config.js +45 -6
- package/dataflow/environments/environment.d.ts +46 -8
- package/dataflow/environments/environment.js +24 -1
- package/dataflow/environments/identifier.d.ts +49 -7
- package/dataflow/environments/identifier.js +11 -2
- package/dataflow/environments/resolve-by-name.d.ts +5 -0
- package/dataflow/environments/resolve-by-name.js +14 -0
- package/dataflow/extractor.js +5 -4
- package/dataflow/graph/dataflowgraph-builder.d.ts +6 -0
- package/dataflow/graph/dataflowgraph-builder.js +8 -0
- package/dataflow/graph/edge.d.ts +10 -4
- package/dataflow/graph/edge.js +12 -5
- package/dataflow/graph/graph.d.ts +41 -3
- package/dataflow/graph/graph.js +39 -34
- package/dataflow/graph/vertex.d.ts +66 -7
- package/dataflow/graph/vertex.js +15 -0
- package/dataflow/info.d.ts +79 -11
- package/dataflow/info.js +20 -0
- package/dataflow/internal/linker.d.ts +4 -2
- package/dataflow/internal/linker.js +12 -5
- package/dataflow/internal/process/functions/call/built-in/built-in-assignment.d.ts +2 -0
- package/dataflow/internal/process/functions/call/built-in/built-in-assignment.js +5 -3
- package/dataflow/internal/process/functions/call/built-in/built-in-expression-list.js +1 -1
- package/dataflow/internal/process/functions/call/built-in/built-in-function-definition.d.ts +16 -0
- package/dataflow/internal/process/functions/call/built-in/built-in-function-definition.js +83 -6
- package/dataflow/internal/process/functions/call/built-in/built-in-if-then-else.js +17 -7
- package/dataflow/internal/process/functions/call/common.js +1 -1
- package/documentation/doc-util/doc-dfg.d.ts +2 -2
- package/documentation/doc-util/doc-dfg.js +11 -16
- package/documentation/doc-util/doc-normalized-ast.js +1 -1
- package/documentation/doc-util/doc-types.d.ts +1 -1
- package/documentation/doc-util/doc-types.js +21 -0
- package/documentation/print-capabilities-markdown.js +1 -1
- package/documentation/print-dataflow-graph-wiki.js +44 -7
- package/documentation/print-linting-and-testing-wiki.js +60 -26
- package/documentation/print-normalized-ast-wiki.js +107 -5
- package/documentation/print-query-wiki.js +8 -1
- package/package.json +17 -3
- package/queries/catalog/call-context-query/call-context-query-executor.js +23 -2
- package/queries/catalog/call-context-query/call-context-query-format.d.ts +29 -2
- package/queries/catalog/call-context-query/call-context-query-format.js +7 -1
- package/queries/catalog/call-context-query/cascade-action.d.ts +8 -0
- package/queries/catalog/call-context-query/cascade-action.js +13 -0
- package/queries/catalog/call-context-query/identify-link-to-last-call-relation.d.ts +11 -1
- package/queries/catalog/call-context-query/identify-link-to-last-call-relation.js +41 -4
- package/queries/catalog/dependencies-query/dependencies-query-format.js +4 -0
- package/queries/query.d.ts +4 -4
- package/queries/query.js +17 -5
- package/r-bridge/lang-4.x/ast/model/model.d.ts +3 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-number.d.ts +5 -1
- package/r-bridge/lang-4.x/ast/model/processing/node-id.d.ts +6 -1
- package/r-bridge/lang-4.x/ast/model/processing/node-id.js +6 -1
- package/r-bridge/lang-4.x/ast/model/processing/visitor.d.ts +1 -1
- package/r-bridge/lang-4.x/ast/model/processing/visitor.js +1 -1
- package/r-bridge/lang-4.x/ast/parser/json/format.js +2 -2
- package/reconstruct/reconstruct.js +1 -1
- package/slicing/static/slice-call.d.ts +7 -2
- package/slicing/static/slice-call.js +33 -44
- package/slicing/static/static-slicer.d.ts +5 -1
- package/slicing/static/static-slicer.js +22 -8
- package/slicing/static/visiting-queue.d.ts +4 -4
- package/slicing/static/visiting-queue.js +5 -3
- package/statistics/output/print-stats.js +2 -1
- package/statistics/summarizer/post-process/histogram.js +2 -1
- package/statistics/summarizer/post-process/post-process-output.js +2 -1
- package/statistics/summarizer/second-phase/process.js +3 -3
- package/util/arrays.d.ts +1 -1
- package/util/arrays.js +3 -3
- package/util/assert.d.ts +1 -1
- package/util/assert.js +3 -2
- package/util/cfg/cfg.js +4 -2
- package/util/mermaid/cfg.js +1 -1
- package/util/summarizer.js +2 -2
- package/util/version.js +1 -1
package/dataflow/graph/graph.js
CHANGED
|
@@ -5,7 +5,6 @@ exports.isPositionalArgument = isPositionalArgument;
|
|
|
5
5
|
exports.isNamedArgument = isNamedArgument;
|
|
6
6
|
exports.getReferenceOfArgument = getReferenceOfArgument;
|
|
7
7
|
const assert_1 = require("../../util/assert");
|
|
8
|
-
const edge_1 = require("./edge");
|
|
9
8
|
const diff_1 = require("./diff");
|
|
10
9
|
const vertex_1 = require("./vertex");
|
|
11
10
|
const arrays_1 = require("../../util/arrays");
|
|
@@ -16,23 +15,27 @@ const clone_1 = require("../environments/clone");
|
|
|
16
15
|
const json_1 = require("../../util/json");
|
|
17
16
|
const built_in_1 = require("../environments/built-in");
|
|
18
17
|
const logger_1 = require("../logger");
|
|
18
|
+
/**
|
|
19
|
+
* Check if the given argument is a {@link PositionalFunctionArgument}.
|
|
20
|
+
*/
|
|
19
21
|
function isPositionalArgument(arg) {
|
|
20
22
|
return arg !== r_function_call_1.EmptyArgument && arg.name === undefined;
|
|
21
23
|
}
|
|
24
|
+
/**
|
|
25
|
+
* Check if the given argument is a {@link NamedFunctionArgument}.
|
|
26
|
+
*/
|
|
22
27
|
function isNamedArgument(arg) {
|
|
23
28
|
return arg !== r_function_call_1.EmptyArgument && arg.name !== undefined;
|
|
24
29
|
}
|
|
30
|
+
/**
|
|
31
|
+
* Returns the reference of a non-empty argument.
|
|
32
|
+
*/
|
|
25
33
|
function getReferenceOfArgument(arg) {
|
|
26
34
|
if (arg !== r_function_call_1.EmptyArgument) {
|
|
27
|
-
return arg
|
|
35
|
+
return arg?.nodeId;
|
|
28
36
|
}
|
|
29
37
|
return undefined;
|
|
30
38
|
}
|
|
31
|
-
function extractEdgeIds(from, to) {
|
|
32
|
-
const fromId = typeof from === 'object' ? from.nodeId : from;
|
|
33
|
-
const toId = typeof to === 'object' ? to.nodeId : to;
|
|
34
|
-
return { fromId, toId };
|
|
35
|
-
}
|
|
36
39
|
/**
|
|
37
40
|
* The dataflow graph holds the dataflow information found within the given AST.
|
|
38
41
|
* We differentiate the directed edges in {@link EdgeType} and the vertices indicated by {@link DataflowGraphVertexArgument}
|
|
@@ -43,6 +46,11 @@ function extractEdgeIds(from, to) {
|
|
|
43
46
|
* However, this does not have to hold during the construction as edges may point from or to vertices which are yet to be constructed.
|
|
44
47
|
*
|
|
45
48
|
* All methods return the modified graph to allow for chaining.
|
|
49
|
+
*
|
|
50
|
+
* @see {@link DataflowGraph#addEdge|`addEdge`} - to add an edge to the graph
|
|
51
|
+
* @see {@link DataflowGraph#addVertex|`addVertex`} - to add a vertex to the graph
|
|
52
|
+
* @see {@link DataflowGraph#fromJson|`fromJson`} - to construct a dataflow graph object from a deserialized JSON object.
|
|
53
|
+
* @see {@link emptyGraph} - to create an empty graph (useful in tests)
|
|
46
54
|
*/
|
|
47
55
|
class DataflowGraph {
|
|
48
56
|
static DEFAULT_ENVIRONMENT = undefined;
|
|
@@ -185,13 +193,10 @@ class DataflowGraph {
|
|
|
185
193
|
return this;
|
|
186
194
|
}
|
|
187
195
|
/**
|
|
188
|
-
* Will insert a new edge into the graph,
|
|
189
|
-
* if the direction of the edge is of no importance (`same-read-read` or `same-def-def`), source
|
|
190
|
-
* and target will be sorted so that `from` has the lower, and `to` the higher id (default ordering).
|
|
191
196
|
* Please note that this will never make edges to {@link BuiltIn} as they are not part of the graph.
|
|
192
197
|
*/
|
|
193
198
|
addEdge(from, to, type) {
|
|
194
|
-
const
|
|
199
|
+
const [fromId, toId] = extractEdgeIds(from, to);
|
|
195
200
|
if (fromId === toId || toId === built_in_1.BuiltIn) {
|
|
196
201
|
return this;
|
|
197
202
|
}
|
|
@@ -206,7 +211,6 @@ class DataflowGraph {
|
|
|
206
211
|
else {
|
|
207
212
|
existingFrom.set(toId, edge);
|
|
208
213
|
}
|
|
209
|
-
this.installEdge(type, toId, fromId, edge);
|
|
210
214
|
}
|
|
211
215
|
else {
|
|
212
216
|
// adding the type
|
|
@@ -214,21 +218,6 @@ class DataflowGraph {
|
|
|
214
218
|
}
|
|
215
219
|
return this;
|
|
216
220
|
}
|
|
217
|
-
installEdge(type, toId, fromId, edge) {
|
|
218
|
-
if (type === edge_1.EdgeType.DefinesOnCall) {
|
|
219
|
-
const otherEdge = {
|
|
220
|
-
...edge,
|
|
221
|
-
types: edge_1.EdgeType.DefinedByOnCall
|
|
222
|
-
};
|
|
223
|
-
const existingTo = this.edgeInformation.get(toId);
|
|
224
|
-
if (existingTo === undefined) {
|
|
225
|
-
this.edgeInformation.set(toId, new Map([[fromId, otherEdge]]));
|
|
226
|
-
}
|
|
227
|
-
else {
|
|
228
|
-
existingTo.set(fromId, otherEdge);
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
221
|
/**
|
|
233
222
|
* Merges the other graph into *this* one (in-place). The return value is only for convenience.
|
|
234
223
|
*
|
|
@@ -269,7 +258,7 @@ class DataflowGraph {
|
|
|
269
258
|
existing.set(target, edge);
|
|
270
259
|
}
|
|
271
260
|
else {
|
|
272
|
-
get.types
|
|
261
|
+
get.types |= edge.types;
|
|
273
262
|
}
|
|
274
263
|
}
|
|
275
264
|
}
|
|
@@ -304,8 +293,17 @@ class DataflowGraph {
|
|
|
304
293
|
const vertex = this.getVertex(from, true);
|
|
305
294
|
(0, assert_1.guard)(vertex !== undefined, () => `node must be defined for ${from} to add control dependency`);
|
|
306
295
|
vertex.controlDependencies ??= [];
|
|
307
|
-
if (to
|
|
308
|
-
|
|
296
|
+
if (to) {
|
|
297
|
+
let hasControlDependency = false;
|
|
298
|
+
for (const { id, when: cond } of vertex.controlDependencies) {
|
|
299
|
+
if (id === to && when !== cond) {
|
|
300
|
+
hasControlDependency = true;
|
|
301
|
+
break;
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
if (!hasControlDependency) {
|
|
305
|
+
vertex.controlDependencies.push({ id: to, when });
|
|
306
|
+
}
|
|
309
307
|
}
|
|
310
308
|
return this;
|
|
311
309
|
}
|
|
@@ -334,8 +332,8 @@ class DataflowGraph {
|
|
|
334
332
|
exports.DataflowGraph = DataflowGraph;
|
|
335
333
|
function mergeNodeInfos(current, next) {
|
|
336
334
|
if (current.tag !== next.tag) {
|
|
337
|
-
logger_1.dataflowLogger.warn(`nodes to be joined for the same id should have the same tag, but ${JSON.stringify(current, json_1.jsonReplacer)} vs. ${JSON.stringify(next, json_1.jsonReplacer)} -- we are currently not handling cases in which vertices may be either! Keeping current.`);
|
|
338
|
-
return
|
|
335
|
+
logger_1.dataflowLogger.warn(() => `nodes to be joined for the same id should have the same tag, but ${JSON.stringify(current, json_1.jsonReplacer)} vs. ${JSON.stringify(next, json_1.jsonReplacer)} -- we are currently not handling cases in which vertices may be either! Keeping current.`);
|
|
336
|
+
return current;
|
|
339
337
|
}
|
|
340
338
|
if (current.tag === vertex_1.VertexType.VariableDefinition) {
|
|
341
339
|
(0, assert_1.guard)(current.scope === next.scope, 'nodes to be joined for the same id must have the same scope');
|
|
@@ -347,7 +345,14 @@ function mergeNodeInfos(current, next) {
|
|
|
347
345
|
(0, assert_1.guard)(current.scope === next.scope, 'nodes to be joined for the same id must have the same scope');
|
|
348
346
|
(0, assert_1.guard)((0, arrays_1.arrayEqual)(current.exitPoints, next.exitPoints), 'nodes to be joined must have same exist points');
|
|
349
347
|
}
|
|
350
|
-
|
|
351
|
-
|
|
348
|
+
return current;
|
|
349
|
+
}
|
|
350
|
+
/**
|
|
351
|
+
* Returns the ids of the dataflow vertices referenced by a {@link ReferenceForEdge}.
|
|
352
|
+
*/
|
|
353
|
+
function extractEdgeIds(from, to) {
|
|
354
|
+
const fromId = typeof from === 'object' ? from.nodeId : from;
|
|
355
|
+
const toId = typeof to === 'object' ? to.nodeId : to;
|
|
356
|
+
return [fromId, toId];
|
|
352
357
|
}
|
|
353
358
|
//# sourceMappingURL=graph.js.map
|
|
@@ -3,7 +3,6 @@ import type { DataflowFunctionFlowInformation, FunctionArgument } from './graph'
|
|
|
3
3
|
import type { NodeId } from '../../r-bridge/lang-4.x/ast/model/processing/node-id';
|
|
4
4
|
import type { REnvironmentInformation } from '../environments/environment';
|
|
5
5
|
import type { ControlDependency } from '../info';
|
|
6
|
-
export type DataflowGraphVertices<Vertex extends DataflowGraphVertexInfo = DataflowGraphVertexInfo> = Map<NodeId, Vertex>;
|
|
7
6
|
export declare enum VertexType {
|
|
8
7
|
Value = "value",
|
|
9
8
|
Use = "use",
|
|
@@ -12,7 +11,7 @@ export declare enum VertexType {
|
|
|
12
11
|
FunctionDefinition = "function-definition"
|
|
13
12
|
}
|
|
14
13
|
/**
|
|
15
|
-
* Arguments required to construct a vertex in the dataflow graph.
|
|
14
|
+
* Arguments required to construct a vertex in the {@link DataflowGraph|dataflow graph}.
|
|
16
15
|
*
|
|
17
16
|
* @see DataflowGraphVertexUse
|
|
18
17
|
* @see DataflowGraphVertexVariableDefinition
|
|
@@ -24,7 +23,9 @@ interface DataflowGraphVertexBase extends MergeableRecord {
|
|
|
24
23
|
*/
|
|
25
24
|
readonly tag: VertexType;
|
|
26
25
|
/**
|
|
27
|
-
* The id of the node (the id assigned by the {@link ParentInformation} decoration)
|
|
26
|
+
* The id of the node (the id assigned by the {@link ParentInformation} decoration).
|
|
27
|
+
* This unanimously identifies the vertex in the {@link DataflowGraph|dataflow graph}
|
|
28
|
+
* as well as the corresponding {@link NormalizedAst|normalized AST}.
|
|
28
29
|
*/
|
|
29
30
|
id: NodeId;
|
|
30
31
|
/**
|
|
@@ -32,19 +33,40 @@ interface DataflowGraphVertexBase extends MergeableRecord {
|
|
|
32
33
|
*/
|
|
33
34
|
environment?: REnvironmentInformation | undefined;
|
|
34
35
|
/**
|
|
35
|
-
*
|
|
36
|
+
* @see {@link ControlDependency} - the collection of control dependencies which have an influence on whether the vertex is executed.
|
|
36
37
|
*/
|
|
37
38
|
controlDependencies: ControlDependency[] | undefined;
|
|
38
39
|
}
|
|
39
40
|
/**
|
|
40
41
|
* Marker vertex for a value in the dataflow of the program.
|
|
42
|
+
* This does not contain the _value_ of the referenced constant
|
|
43
|
+
* as this is available with the {@link DataflowGraphVertexBase#id|id} in the {@link NormalizedAst|normalized AST}
|
|
44
|
+
* (or more specifically the {@link AstIdMap}).
|
|
45
|
+
*
|
|
46
|
+
* If you have a {@link DataflowGraph|dataflow graph} named `graph`
|
|
47
|
+
* with an {@link AstIdMap} and a value vertex object with name `value` the following Code should work:
|
|
48
|
+
*
|
|
49
|
+
* @example
|
|
50
|
+
* ```ts
|
|
51
|
+
* const node = graph.idMap.get(value.id)
|
|
52
|
+
* ```
|
|
53
|
+
*
|
|
54
|
+
* This then returns the corresponding node in the {@link NormalizedAst|normalized AST}, for example,
|
|
55
|
+
* an {@link RNumber} or {@link RString}.
|
|
56
|
+
*
|
|
57
|
+
* This works similarly for {@link IdentifierReference|identifier references}
|
|
58
|
+
* for which you can use the {@link IdentifierReference#nodeId|`nodeId`}.
|
|
59
|
+
*
|
|
60
|
+
* @see {@link isValueVertex} - to check if a vertex is a value vertex
|
|
41
61
|
*/
|
|
42
62
|
export interface DataflowGraphVertexValue extends DataflowGraphVertexBase {
|
|
43
63
|
readonly tag: VertexType.Value;
|
|
44
64
|
readonly environment?: undefined;
|
|
45
65
|
}
|
|
46
66
|
/**
|
|
47
|
-
* Arguments required to construct a vertex which represents the usage of a variable in the dataflow graph.
|
|
67
|
+
* Arguments required to construct a vertex which represents the usage of a variable in the {@link DataflowGraph|dataflow graph}.
|
|
68
|
+
*
|
|
69
|
+
* @see {@link isUseVertex} - to check if a vertex is a use vertex
|
|
48
70
|
*/
|
|
49
71
|
export interface DataflowGraphVertexUse extends DataflowGraphVertexBase {
|
|
50
72
|
readonly tag: VertexType.Use;
|
|
@@ -52,7 +74,9 @@ export interface DataflowGraphVertexUse extends DataflowGraphVertexBase {
|
|
|
52
74
|
readonly environment?: undefined;
|
|
53
75
|
}
|
|
54
76
|
/**
|
|
55
|
-
* Arguments required to construct a vertex which represents the usage of a variable in the dataflow graph.
|
|
77
|
+
* Arguments required to construct a vertex which represents the usage of a variable in the {@link DataflowGraph|dataflow graph}.
|
|
78
|
+
*
|
|
79
|
+
* @see {@link isFunctionCallVertex} - to check if a vertex is a function call vertex
|
|
56
80
|
*/
|
|
57
81
|
export interface DataflowGraphVertexFunctionCall extends DataflowGraphVertexBase {
|
|
58
82
|
readonly tag: VertexType.FunctionCall;
|
|
@@ -71,13 +95,20 @@ export interface DataflowGraphVertexFunctionCall extends DataflowGraphVertexBase
|
|
|
71
95
|
environment: REnvironmentInformation | undefined;
|
|
72
96
|
}
|
|
73
97
|
/**
|
|
74
|
-
* Arguments required to construct a vertex which represents the definition of a variable in the dataflow graph.
|
|
98
|
+
* Arguments required to construct a vertex which represents the definition of a variable in the {@link DataflowGraph|dataflow graph}.
|
|
99
|
+
*
|
|
100
|
+
* @see {@link isVariableDefinitionVertex} - to check if a vertex is a variable definition vertex
|
|
75
101
|
*/
|
|
76
102
|
export interface DataflowGraphVertexVariableDefinition extends DataflowGraphVertexBase {
|
|
77
103
|
readonly tag: VertexType.VariableDefinition;
|
|
78
104
|
/** Does not require an environment, those are attached to the call */
|
|
79
105
|
readonly environment?: undefined;
|
|
80
106
|
}
|
|
107
|
+
/**
|
|
108
|
+
* Arguments required to construct a vertex which represents the definition of a function in the {@link DataflowGraph|dataflow graph}.
|
|
109
|
+
*
|
|
110
|
+
* @see {@link isFunctionDefinitionVertex} - to check if a vertex is a function definition vertex
|
|
111
|
+
*/
|
|
81
112
|
export interface DataflowGraphVertexFunctionDefinition extends DataflowGraphVertexBase {
|
|
82
113
|
readonly tag: VertexType.FunctionDefinition;
|
|
83
114
|
/**
|
|
@@ -93,11 +124,39 @@ export interface DataflowGraphVertexFunctionDefinition extends DataflowGraphVert
|
|
|
93
124
|
exitPoints: readonly NodeId[];
|
|
94
125
|
environment?: REnvironmentInformation;
|
|
95
126
|
}
|
|
127
|
+
/**
|
|
128
|
+
* What is to be passed to construct a vertex in the {@link DataflowGraph|dataflow graph}
|
|
129
|
+
*/
|
|
96
130
|
export type DataflowGraphVertexArgument = DataflowGraphVertexUse | DataflowGraphVertexVariableDefinition | DataflowGraphVertexFunctionDefinition | DataflowGraphVertexFunctionCall | DataflowGraphVertexValue;
|
|
131
|
+
/**
|
|
132
|
+
* This is the union type of all possible vertices that appear within a {@link DataflowGraph|dataflow graph},
|
|
133
|
+
* they can be constructed passing a {@link DataflowGraphVertexArgument} to the graph.
|
|
134
|
+
*
|
|
135
|
+
* See {@link DataflowGraphVertices} for an id-based mapping.
|
|
136
|
+
*/
|
|
97
137
|
export type DataflowGraphVertexInfo = Required<DataflowGraphVertexArgument>;
|
|
138
|
+
/**
|
|
139
|
+
* A mapping of {@link NodeId}s to {@link DataflowGraphVertexInfo|vertices}.
|
|
140
|
+
*/
|
|
141
|
+
export type DataflowGraphVertices<Vertex extends DataflowGraphVertexInfo = DataflowGraphVertexInfo> = Map<NodeId, Vertex>;
|
|
142
|
+
/**
|
|
143
|
+
* Check if the given vertex is a {@link DataflowGraphVertexValue|value vertex}.
|
|
144
|
+
*/
|
|
98
145
|
export declare function isValueVertex(vertex: DataflowGraphVertexBase): vertex is DataflowGraphVertexValue;
|
|
146
|
+
/**
|
|
147
|
+
* Check if the given vertex is a {@link DataflowGraphVertexUse|use vertex}.
|
|
148
|
+
*/
|
|
99
149
|
export declare function isUseVertex(vertex: DataflowGraphVertexBase): vertex is DataflowGraphVertexUse;
|
|
150
|
+
/**
|
|
151
|
+
* Check if the given vertex is a {@link DataflowGraphVertexFunctionCall|function call vertex}.
|
|
152
|
+
*/
|
|
100
153
|
export declare function isFunctionCallVertex(vertex: DataflowGraphVertexBase): vertex is DataflowGraphVertexFunctionCall;
|
|
154
|
+
/**
|
|
155
|
+
* Check if the given vertex is a {@link DataflowGraphVertexVariableDefinition|variable definition vertex}.
|
|
156
|
+
*/
|
|
101
157
|
export declare function isVariableDefinitionVertex(vertex: DataflowGraphVertexBase): vertex is DataflowGraphVertexVariableDefinition;
|
|
158
|
+
/**
|
|
159
|
+
* Check if the given vertex is a {@link DataflowGraphVertexFunctionDefinition|function definition vertex}.
|
|
160
|
+
*/
|
|
102
161
|
export declare function isFunctionDefinitionVertex(vertex: DataflowGraphVertexBase): vertex is DataflowGraphVertexFunctionDefinition;
|
|
103
162
|
export {};
|
package/dataflow/graph/vertex.js
CHANGED
|
@@ -14,18 +14,33 @@ var VertexType;
|
|
|
14
14
|
VertexType["VariableDefinition"] = "variable-definition";
|
|
15
15
|
VertexType["FunctionDefinition"] = "function-definition";
|
|
16
16
|
})(VertexType || (exports.VertexType = VertexType = {}));
|
|
17
|
+
/**
|
|
18
|
+
* Check if the given vertex is a {@link DataflowGraphVertexValue|value vertex}.
|
|
19
|
+
*/
|
|
17
20
|
function isValueVertex(vertex) {
|
|
18
21
|
return vertex.tag === VertexType.Value;
|
|
19
22
|
}
|
|
23
|
+
/**
|
|
24
|
+
* Check if the given vertex is a {@link DataflowGraphVertexUse|use vertex}.
|
|
25
|
+
*/
|
|
20
26
|
function isUseVertex(vertex) {
|
|
21
27
|
return vertex.tag === VertexType.Use;
|
|
22
28
|
}
|
|
29
|
+
/**
|
|
30
|
+
* Check if the given vertex is a {@link DataflowGraphVertexFunctionCall|function call vertex}.
|
|
31
|
+
*/
|
|
23
32
|
function isFunctionCallVertex(vertex) {
|
|
24
33
|
return vertex.tag === VertexType.FunctionCall;
|
|
25
34
|
}
|
|
35
|
+
/**
|
|
36
|
+
* Check if the given vertex is a {@link DataflowGraphVertexVariableDefinition|variable definition vertex}.
|
|
37
|
+
*/
|
|
26
38
|
function isVariableDefinitionVertex(vertex) {
|
|
27
39
|
return vertex.tag === VertexType.VariableDefinition;
|
|
28
40
|
}
|
|
41
|
+
/**
|
|
42
|
+
* Check if the given vertex is a {@link DataflowGraphVertexFunctionDefinition|function definition vertex}.
|
|
43
|
+
*/
|
|
29
44
|
function isFunctionDefinitionVertex(vertex) {
|
|
30
45
|
return vertex.tag === VertexType.FunctionDefinition;
|
|
31
46
|
}
|
package/dataflow/info.d.ts
CHANGED
|
@@ -4,6 +4,24 @@ import type { IdentifierReference } from './environments/identifier';
|
|
|
4
4
|
import type { REnvironmentInformation } from './environments/environment';
|
|
5
5
|
import { DataflowGraph } from './graph/graph';
|
|
6
6
|
import type { GenericDifferenceInformation, WriteableDifferenceReport } from '../util/diff';
|
|
7
|
+
/**
|
|
8
|
+
* A control dependency links a vertex to the control flow element which
|
|
9
|
+
* may have an influence on its execution.
|
|
10
|
+
* Within `if(p) a else b`, `a` and `b` have a control dependency on the `if` (which in turn decides based on `p`).
|
|
11
|
+
*
|
|
12
|
+
* @see {@link happensInEveryBranch} - to check whether a list of control dependencies is exhaustive
|
|
13
|
+
*/
|
|
14
|
+
export interface ControlDependency {
|
|
15
|
+
/** The id of the node that causes the control dependency to be active (e.g., the condition of an if) */
|
|
16
|
+
readonly id: NodeId;
|
|
17
|
+
/** when does this control dependency trigger (if the condition is true or false)? */
|
|
18
|
+
readonly when?: boolean;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Classifies the type of exit point encountered.
|
|
22
|
+
*
|
|
23
|
+
* @see {@link ExitPoint}
|
|
24
|
+
*/
|
|
7
25
|
export declare const enum ExitPointType {
|
|
8
26
|
/** The exit point is the implicit (last executed expression of a function/block) */
|
|
9
27
|
Default = 0,
|
|
@@ -14,20 +32,31 @@ export declare const enum ExitPointType {
|
|
|
14
32
|
/** The exit point is an explicit `next` call (or an alias of it) */
|
|
15
33
|
Next = 3
|
|
16
34
|
}
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
}
|
|
35
|
+
/**
|
|
36
|
+
* An exit point describes the position which ends the current control flow structure.
|
|
37
|
+
* This may be as innocent as the last expression or explicit with a `return`/`break`/`next`.
|
|
38
|
+
*
|
|
39
|
+
* @see {@link ExitPointType} - for the different types of exit points
|
|
40
|
+
* @see {@link addNonDefaultExitPoints} - to easily modify lists of exit points
|
|
41
|
+
* @see {@link alwaysExits} - to check whether a list of control dependencies always triggers an exit
|
|
42
|
+
* @see {@link filterOutLoopExitPoints} - to remove loop exit points from a list
|
|
43
|
+
*/
|
|
23
44
|
export interface ExitPoint {
|
|
24
45
|
/** What kind of exit point is this one? May be used to filter for exit points of specific causes. */
|
|
25
46
|
readonly type: ExitPointType;
|
|
26
47
|
/** The id of the node which causes the exit point! */
|
|
27
48
|
readonly nodeId: NodeId;
|
|
28
|
-
/**
|
|
49
|
+
/**
|
|
50
|
+
* Control dependencies which influence if the exit point triggers
|
|
51
|
+
* (e.g., if the `return` is contained within an `if` statement).
|
|
52
|
+
*
|
|
53
|
+
* @see {@link happensInEveryBranch} - to check whether control dependencies are exhaustive
|
|
54
|
+
*/
|
|
29
55
|
readonly controlDependencies: ControlDependency[] | undefined;
|
|
30
56
|
}
|
|
57
|
+
/**
|
|
58
|
+
* Adds all non-default exit points to the existing list.
|
|
59
|
+
*/
|
|
31
60
|
export declare function addNonDefaultExitPoints(existing: ExitPoint[], add: readonly ExitPoint[]): void;
|
|
32
61
|
/** The control flow information for the current DataflowInformation. */
|
|
33
62
|
export interface DataflowCfgInformation {
|
|
@@ -37,24 +66,63 @@ export interface DataflowCfgInformation {
|
|
|
37
66
|
exitPoints: readonly ExitPoint[];
|
|
38
67
|
}
|
|
39
68
|
/**
|
|
40
|
-
* The dataflow information is
|
|
69
|
+
* The dataflow information is one of the fundamental structures we have in the dataflow analysis.
|
|
70
|
+
* It is continuously updated during the dataflow analysis
|
|
41
71
|
* and holds its current state for the respective subtree processed.
|
|
72
|
+
* Each processor during the dataflow analysis may use the information from its children
|
|
73
|
+
* to produce a new state of the dataflow information.
|
|
74
|
+
*
|
|
75
|
+
* You may initialize a new dataflow information with {@link initializeCleanDataflowInformation}.
|
|
76
|
+
*
|
|
77
|
+
* @see {@link DataflowCfgInformation} - the control flow aspects
|
|
42
78
|
*/
|
|
43
79
|
export interface DataflowInformation extends DataflowCfgInformation {
|
|
44
|
-
/**
|
|
80
|
+
/**
|
|
81
|
+
* References that have not been identified as read or write and will be so on higher processors.
|
|
82
|
+
*
|
|
83
|
+
* For example, when we analyze the `x` vertex in `x <- 3`, we will first create an unknown reference for `x`
|
|
84
|
+
* as we have not yet seen the assignment!
|
|
85
|
+
*
|
|
86
|
+
* @see {@link IdentifierReference} - a reference on a variable, parameter, function call, ...
|
|
87
|
+
*/
|
|
45
88
|
unknownReferences: readonly IdentifierReference[];
|
|
46
|
-
/**
|
|
89
|
+
/**
|
|
90
|
+
* References which are read within the current subtree.
|
|
91
|
+
*
|
|
92
|
+
* @see {@link IdentifierReference} - a reference on a variable, parameter, function call, ...
|
|
93
|
+
* */
|
|
47
94
|
in: readonly IdentifierReference[];
|
|
48
|
-
/**
|
|
95
|
+
/**
|
|
96
|
+
* References which are written to within the current subtree
|
|
97
|
+
*
|
|
98
|
+
* @see {@link IdentifierReference} - a reference on a variable, parameter, function call, ...
|
|
99
|
+
*/
|
|
49
100
|
out: readonly IdentifierReference[];
|
|
50
101
|
/** Current environments used for name resolution, probably updated on the next expression-list processing */
|
|
51
102
|
environment: REnvironmentInformation;
|
|
52
103
|
/** The current constructed dataflow graph */
|
|
53
104
|
graph: DataflowGraph;
|
|
54
105
|
}
|
|
106
|
+
/**
|
|
107
|
+
* Initializes an empty {@link DataflowInformation} object with the given entry point and data.
|
|
108
|
+
* This is to be used as a "starting point" when processing leaf nodes during the dataflow extraction.
|
|
109
|
+
*
|
|
110
|
+
* @see {@link DataflowInformation}
|
|
111
|
+
*/
|
|
55
112
|
export declare function initializeCleanDataflowInformation<T>(entryPoint: NodeId, data: Pick<DataflowProcessorInformation<T>, 'environment' | 'completeAst'>): DataflowInformation;
|
|
113
|
+
/**
|
|
114
|
+
* Checks whether the given control dependencies are exhaustive (i.e. if for every control dependency on a boolean,
|
|
115
|
+
* the list contains a dependency on the `true` and on the `false` case).
|
|
116
|
+
*/
|
|
56
117
|
export declare function happensInEveryBranch(controlDependencies: readonly ControlDependency[] | undefined): boolean;
|
|
118
|
+
/**
|
|
119
|
+
* Checks whether the given dataflow information always exits (i.e., if there is a non-default exit point in every branch).
|
|
120
|
+
* @see {@link ExitPoint} - for the different types of exit points
|
|
121
|
+
*/
|
|
57
122
|
export declare function alwaysExits(data: DataflowInformation): boolean;
|
|
123
|
+
/**
|
|
124
|
+
* Filters out exit points which end their cascade within a loop.
|
|
125
|
+
*/
|
|
58
126
|
export declare function filterOutLoopExitPoints(exitPoints: readonly ExitPoint[]): readonly ExitPoint[];
|
|
59
127
|
export declare function diffControlDependency<Report extends WriteableDifferenceReport>(a: ControlDependency | undefined, b: ControlDependency | undefined, info: GenericDifferenceInformation<Report>): void;
|
|
60
128
|
export declare function diffControlDependencies<Report extends WriteableDifferenceReport>(a: ControlDependency[] | undefined, b: ControlDependency[] | undefined, info: GenericDifferenceInformation<Report>): void;
|
package/dataflow/info.js
CHANGED
|
@@ -8,9 +8,18 @@ exports.filterOutLoopExitPoints = filterOutLoopExitPoints;
|
|
|
8
8
|
exports.diffControlDependency = diffControlDependency;
|
|
9
9
|
exports.diffControlDependencies = diffControlDependencies;
|
|
10
10
|
const graph_1 = require("./graph/graph");
|
|
11
|
+
/**
|
|
12
|
+
* Adds all non-default exit points to the existing list.
|
|
13
|
+
*/
|
|
11
14
|
function addNonDefaultExitPoints(existing, add) {
|
|
12
15
|
existing.push(...add.filter(({ type }) => type !== 0 /* ExitPointType.Default */));
|
|
13
16
|
}
|
|
17
|
+
/**
|
|
18
|
+
* Initializes an empty {@link DataflowInformation} object with the given entry point and data.
|
|
19
|
+
* This is to be used as a "starting point" when processing leaf nodes during the dataflow extraction.
|
|
20
|
+
*
|
|
21
|
+
* @see {@link DataflowInformation}
|
|
22
|
+
*/
|
|
14
23
|
function initializeCleanDataflowInformation(entryPoint, data) {
|
|
15
24
|
return {
|
|
16
25
|
unknownReferences: [],
|
|
@@ -22,6 +31,10 @@ function initializeCleanDataflowInformation(entryPoint, data) {
|
|
|
22
31
|
exitPoints: [{ nodeId: entryPoint, type: 0 /* ExitPointType.Default */, controlDependencies: undefined }]
|
|
23
32
|
};
|
|
24
33
|
}
|
|
34
|
+
/**
|
|
35
|
+
* Checks whether the given control dependencies are exhaustive (i.e. if for every control dependency on a boolean,
|
|
36
|
+
* the list contains a dependency on the `true` and on the `false` case).
|
|
37
|
+
*/
|
|
25
38
|
function happensInEveryBranch(controlDependencies) {
|
|
26
39
|
if (controlDependencies === undefined) {
|
|
27
40
|
/* the cds are unconstrained */
|
|
@@ -43,9 +56,16 @@ function happensInEveryBranch(controlDependencies) {
|
|
|
43
56
|
}
|
|
44
57
|
return trues.every(id => falseSet.has(id));
|
|
45
58
|
}
|
|
59
|
+
/**
|
|
60
|
+
* Checks whether the given dataflow information always exits (i.e., if there is a non-default exit point in every branch).
|
|
61
|
+
* @see {@link ExitPoint} - for the different types of exit points
|
|
62
|
+
*/
|
|
46
63
|
function alwaysExits(data) {
|
|
47
64
|
return data.exitPoints?.some(e => e.type !== 0 /* ExitPointType.Default */ && happensInEveryBranch(e.controlDependencies)) ?? false;
|
|
48
65
|
}
|
|
66
|
+
/**
|
|
67
|
+
* Filters out exit points which end their cascade within a loop.
|
|
68
|
+
*/
|
|
49
69
|
function filterOutLoopExitPoints(exitPoints) {
|
|
50
70
|
return exitPoints.filter(({ type }) => type === 1 /* ExitPointType.Return */ || type === 0 /* ExitPointType.Default */);
|
|
51
71
|
}
|
|
@@ -23,8 +23,10 @@ export declare function linkFunctionCalls(graph: DataflowGraph, idMap: AstIdMap,
|
|
|
23
23
|
functionCall: NodeId;
|
|
24
24
|
called: readonly DataflowGraphVertexInfo[];
|
|
25
25
|
}[];
|
|
26
|
-
/**
|
|
27
|
-
|
|
26
|
+
/**
|
|
27
|
+
* convenience function returning all known call targets, as well as the name source which defines them
|
|
28
|
+
*/
|
|
29
|
+
export declare function getAllFunctionCallTargets(call: NodeId, graph: DataflowGraph, environment?: REnvironmentInformation): NodeId[];
|
|
28
30
|
export declare function getAllLinkedFunctionDefinitions(functionDefinitionReadIds: ReadonlySet<NodeId>, dataflowGraph: DataflowGraph): Set<DataflowGraphVertexInfo>;
|
|
29
31
|
/**
|
|
30
32
|
* This method links a set of read variables to definitions in an environment.
|
|
@@ -84,11 +84,13 @@ function linkArgumentsOnCall(args, params, graph) {
|
|
|
84
84
|
if (param !== undefined) {
|
|
85
85
|
logger_1.dataflowLogger.trace(`mapping named argument "${name}" to parameter "${param.name.content}"`);
|
|
86
86
|
graph.addEdge(arg.nodeId, param.name.info.id, edge_1.EdgeType.DefinesOnCall);
|
|
87
|
+
graph.addEdge(param.name.info.id, arg.nodeId, edge_1.EdgeType.DefinedByOnCall);
|
|
87
88
|
matchedParameters.add(name);
|
|
88
89
|
}
|
|
89
90
|
else if (specialDotParameter !== undefined) {
|
|
90
91
|
logger_1.dataflowLogger.trace(`mapping named argument "${name}" to dot-dot-dot parameter`);
|
|
91
92
|
graph.addEdge(arg.nodeId, specialDotParameter.name.info.id, edge_1.EdgeType.DefinesOnCall);
|
|
93
|
+
graph.addEdge(specialDotParameter.name.info.id, arg.nodeId, edge_1.EdgeType.DefinedByOnCall);
|
|
92
94
|
}
|
|
93
95
|
}
|
|
94
96
|
const remainingParameter = params.filter(p => !matchedParameters.has(p.name.content));
|
|
@@ -103,6 +105,7 @@ function linkArgumentsOnCall(args, params, graph) {
|
|
|
103
105
|
if (specialDotParameter !== undefined) {
|
|
104
106
|
logger_1.dataflowLogger.trace(`mapping unnamed argument ${i} (id: ${arg.nodeId}) to dot-dot-dot parameter`);
|
|
105
107
|
graph.addEdge(arg.nodeId, specialDotParameter.name.info.id, edge_1.EdgeType.DefinesOnCall);
|
|
108
|
+
graph.addEdge(specialDotParameter.name.info.id, arg.nodeId, edge_1.EdgeType.DefinedByOnCall);
|
|
106
109
|
}
|
|
107
110
|
else {
|
|
108
111
|
logger_1.dataflowLogger.warn(`skipping argument ${i} as there is no corresponding parameter - R should block that`);
|
|
@@ -112,6 +115,7 @@ function linkArgumentsOnCall(args, params, graph) {
|
|
|
112
115
|
const param = remainingParameter[i];
|
|
113
116
|
logger_1.dataflowLogger.trace(`mapping unnamed argument ${i} (id: ${arg.nodeId}) to parameter "${param.name.content}"`);
|
|
114
117
|
graph.addEdge(arg.nodeId, param.name.info.id, edge_1.EdgeType.DefinesOnCall);
|
|
118
|
+
graph.addEdge(param.name.info.id, arg.nodeId, edge_1.EdgeType.DefinedByOnCall);
|
|
115
119
|
}
|
|
116
120
|
}
|
|
117
121
|
function linkFunctionCallArguments(targetId, idMap, functionCallName, functionRootId, callArgs, finalGraph) {
|
|
@@ -138,7 +142,8 @@ function linkFunctionCallWithSingleTarget(graph, def, info, idMap) {
|
|
|
138
142
|
continue;
|
|
139
143
|
}
|
|
140
144
|
for (const def of defs) {
|
|
141
|
-
graph.addEdge(
|
|
145
|
+
graph.addEdge(ingoing, def, edge_1.EdgeType.DefinedByOnCall);
|
|
146
|
+
graph.addEdge(id, def, edge_1.EdgeType.DefinesOnCall);
|
|
142
147
|
}
|
|
143
148
|
}
|
|
144
149
|
}
|
|
@@ -187,8 +192,10 @@ function linkFunctionCalls(graph, idMap, thisGraph) {
|
|
|
187
192
|
}
|
|
188
193
|
return calledFunctionDefinitions;
|
|
189
194
|
}
|
|
190
|
-
/**
|
|
191
|
-
function
|
|
195
|
+
/**
|
|
196
|
+
* convenience function returning all known call targets, as well as the name source which defines them
|
|
197
|
+
*/
|
|
198
|
+
function getAllFunctionCallTargets(call, graph, environment) {
|
|
192
199
|
const found = [];
|
|
193
200
|
const callVertex = graph.get(call, true);
|
|
194
201
|
if (callVertex === undefined) {
|
|
@@ -198,8 +205,8 @@ function getAllFunctionCallTargets(call, graph) {
|
|
|
198
205
|
if (info.tag !== vertex_1.VertexType.FunctionCall) {
|
|
199
206
|
return [];
|
|
200
207
|
}
|
|
201
|
-
if (info.name !== undefined && info.environment !== undefined) {
|
|
202
|
-
const functionCallDefs = (0, resolve_by_name_1.resolveByName)(info.name, info.environment, identifier_1.ReferenceType.Function)?.map(d => d.nodeId) ?? [];
|
|
208
|
+
if (info.name !== undefined && (environment !== undefined || info.environment !== undefined)) {
|
|
209
|
+
const functionCallDefs = (0, resolve_by_name_1.resolveByName)(info.name, environment ?? info.environment, identifier_1.ReferenceType.Function)?.map(d => d.nodeId) ?? [];
|
|
203
210
|
for (const [target, outgoingEdge] of outgoingEdges.entries()) {
|
|
204
211
|
if ((0, edge_1.edgeIncludesType)(outgoingEdge.types, edge_1.EdgeType.Calls)) {
|
|
205
212
|
functionCallDefs.push(target);
|
|
@@ -15,6 +15,8 @@ export interface AssignmentConfiguration extends ForceArguments {
|
|
|
15
15
|
readonly makeMaybe?: boolean;
|
|
16
16
|
readonly quoteSource?: boolean;
|
|
17
17
|
readonly canBeReplacement?: boolean;
|
|
18
|
+
/** is the target a variable pointing at the actual name? */
|
|
19
|
+
readonly targetVariable?: boolean;
|
|
18
20
|
}
|
|
19
21
|
/**
|
|
20
22
|
* Processes an assignment, i.e., `<target> <- <source>`.
|
|
@@ -57,7 +57,7 @@ args, rootId, data, config) {
|
|
|
57
57
|
const effectiveArgs = getEffectiveOrder(config, args);
|
|
58
58
|
const { target, source } = extractSourceAndTarget(effectiveArgs, name);
|
|
59
59
|
const { type, named } = target;
|
|
60
|
-
if (type === type_1.RType.Symbol) {
|
|
60
|
+
if (!config.targetVariable && type === type_1.RType.Symbol) {
|
|
61
61
|
const res = (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data, reverseOrder: !config.swapSourceAndTarget, forceArgs: config.forceArgs });
|
|
62
62
|
return processAssignmentToSymbol({
|
|
63
63
|
...config,
|
|
@@ -107,8 +107,10 @@ args, rootId, data, config) {
|
|
|
107
107
|
else if (type === type_1.RType.String) {
|
|
108
108
|
return processAssignmentToString(target, args, name, rootId, data, config, source);
|
|
109
109
|
}
|
|
110
|
-
logger_1.dataflowLogger.warn(`Assignment ${name.content} has an unknown target type ${target.type}
|
|
111
|
-
|
|
110
|
+
logger_1.dataflowLogger.warn(`Assignment ${name.content} has an unknown target type ${target.type} => unknown impact`);
|
|
111
|
+
const info = (0, known_call_handling_1.processKnownFunctionCall)({ name, args: effectiveArgs, rootId, data, forceArgs: config.forceArgs }).information;
|
|
112
|
+
info.graph.markIdForUnknownSideEffects(rootId);
|
|
113
|
+
return info;
|
|
112
114
|
}
|
|
113
115
|
function extractSourceAndTarget(args, name) {
|
|
114
116
|
const source = (0, unpack_argument_1.unpackArgument)(args[1], false);
|
|
@@ -53,7 +53,7 @@ function updateSideEffectsForCalledFunctions(calledEnvs, inputEnvironment, nextG
|
|
|
53
53
|
for (const { functionCall, called } of calledEnvs) {
|
|
54
54
|
const callDependencies = nextGraph.getVertex(functionCall, true)?.controlDependencies;
|
|
55
55
|
for (const calledFn of called) {
|
|
56
|
-
(0, assert_1.guard)(calledFn.tag === vertex_1.VertexType.FunctionDefinition, 'called function must
|
|
56
|
+
(0, assert_1.guard)(calledFn.tag === vertex_1.VertexType.FunctionDefinition, 'called function must be a function definition');
|
|
57
57
|
// only merge the environments they have in common
|
|
58
58
|
let environment = calledFn.environment;
|
|
59
59
|
while (environment.level > inputEnvironment.level) {
|
|
@@ -4,4 +4,20 @@ import type { ParentInformation } from '../../../../../../r-bridge/lang-4.x/ast/
|
|
|
4
4
|
import type { RSymbol } from '../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-symbol';
|
|
5
5
|
import type { RFunctionArgument } from '../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-function-call';
|
|
6
6
|
import type { NodeId } from '../../../../../../r-bridge/lang-4.x/ast/model/processing/node-id';
|
|
7
|
+
import { DataflowGraph } from '../../../../../graph/graph';
|
|
8
|
+
import type { REnvironmentInformation } from '../../../../../environments/environment';
|
|
7
9
|
export declare function processFunctionDefinition<OtherInfo>(name: RSymbol<OtherInfo & ParentInformation>, args: readonly RFunctionArgument<OtherInfo & ParentInformation>[], rootId: NodeId, data: DataflowProcessorInformation<OtherInfo & ParentInformation>): DataflowInformation;
|
|
10
|
+
export declare function retrieveActiveEnvironment(callerEnvironment: REnvironmentInformation | undefined, baseEnvironment: REnvironmentInformation): REnvironmentInformation;
|
|
11
|
+
/**
|
|
12
|
+
* Update the closure links of all nested function definitions
|
|
13
|
+
* @param graph - dataflow graph to collect the function definitions from and to update the closure links for
|
|
14
|
+
* @param outEnvironment - active environment on resolving closures (i.e., exit of the function definition)
|
|
15
|
+
* @param fnId - id of the function definition to update the closure links for
|
|
16
|
+
*/
|
|
17
|
+
export declare function updateNestedFunctionClosures(graph: DataflowGraph, outEnvironment: REnvironmentInformation, fnId: NodeId): void;
|
|
18
|
+
/**
|
|
19
|
+
* Update the closure links of all nested function calls, this is probably to be done once at the end of the script
|
|
20
|
+
* @param graph - dataflow graph to collect the function calls from and to update the closure links for
|
|
21
|
+
* @param outEnvironment - active environment on resolving closures (i.e., exit of the function definition)
|
|
22
|
+
*/
|
|
23
|
+
export declare function updateNestedFunctionCalls(graph: DataflowGraph, outEnvironment: REnvironmentInformation): void;
|