@eagleoutice/flowr 2.9.14 → 2.10.1
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 +37 -25
- package/benchmark/stats/stats.d.ts +2 -2
- package/cli/repl/parser/slice-query-parser.d.ts +2 -2
- package/config.d.ts +4 -0
- package/config.js +5 -3
- package/dataflow/environments/identifier.d.ts +4 -0
- package/dataflow/environments/identifier.js +17 -0
- package/dataflow/graph/call-graph.d.ts +4 -7
- package/dataflow/graph/call-graph.js +0 -22
- package/dataflow/graph/df-helper.d.ts +9 -8
- package/dataflow/graph/df-helper.js +9 -2
- package/dataflow/graph/graph-helper.d.ts +9 -4
- package/dataflow/graph/graph-helper.js +26 -3
- package/dataflow/graph/graph.d.ts +13 -2
- package/dataflow/graph/graph.js +26 -4
- package/dataflow/graph/vertex.d.ts +2 -0
- package/dataflow/internal/process/functions/call/built-in/built-in-apply.js +1 -0
- package/dataflow/internal/process/functions/call/built-in/built-in-assignment.js +1 -1
- package/dataflow/internal/process/functions/call/built-in/built-in-for-loop.js +1 -1
- package/dataflow/internal/process/functions/call/built-in/built-in-function-definition.js +2 -2
- package/dataflow/internal/process/functions/call/common.js +2 -1
- package/dataflow/internal/process/functions/process-parameter.js +1 -1
- package/documentation/doc-readme.js +2 -1
- package/documentation/wiki-linter.js +5 -0
- package/linter/linter-rules.d.ts +25 -0
- package/linter/linter-rules.js +2 -0
- package/linter/rules/problematic-eval.d.ts +44 -0
- package/linter/rules/problematic-eval.js +83 -0
- package/package.json +7 -7
- package/queries/catalog/df-shape-query/df-shape-query-executor.js +1 -1
- package/queries/catalog/df-shape-query/df-shape-query-format.d.ts +3 -3
- package/queries/catalog/does-call-query/does-call-query-executor.js +1 -1
- package/queries/catalog/does-call-query/does-call-query-format.d.ts +2 -2
- package/queries/catalog/happens-before-query/happens-before-query-executor.js +2 -2
- package/queries/catalog/happens-before-query/happens-before-query-format.d.ts +3 -3
- package/queries/catalog/input-sources-query/input-sources-query-executor.d.ts +6 -0
- package/queries/catalog/input-sources-query/input-sources-query-executor.js +66 -0
- package/queries/catalog/input-sources-query/input-sources-query-format.d.ts +36 -0
- package/queries/catalog/input-sources-query/input-sources-query-format.js +63 -0
- package/queries/catalog/input-sources-query/simple-input-classifier.d.ts +90 -0
- package/queries/catalog/input-sources-query/simple-input-classifier.js +308 -0
- package/queries/catalog/inspect-exceptions-query/inspect-exception-query-executor.d.ts +2 -2
- package/queries/catalog/inspect-exceptions-query/inspect-exception-query-executor.js +1 -1
- package/queries/catalog/inspect-exceptions-query/inspect-exception-query-format.d.ts +2 -2
- package/queries/catalog/inspect-higher-order-query/inspect-higher-order-query-executor.js +1 -1
- package/queries/catalog/inspect-higher-order-query/inspect-higher-order-query-format.d.ts +2 -2
- package/queries/catalog/inspect-recursion-query/inspect-recursion-query-format.d.ts +2 -2
- package/queries/catalog/location-map-query/location-map-query-executor.js +1 -1
- package/queries/catalog/location-map-query/location-map-query-format.d.ts +2 -2
- package/queries/catalog/origin-query/origin-query-executor.d.ts +2 -2
- package/queries/catalog/origin-query/origin-query-executor.js +1 -1
- package/queries/catalog/origin-query/origin-query-format.d.ts +3 -3
- package/queries/catalog/provenance-query/provenance-query-executor.d.ts +1 -4
- package/queries/catalog/provenance-query/provenance-query-executor.js +3 -6
- package/queries/catalog/provenance-query/provenance-query-format.d.ts +2 -2
- package/queries/catalog/resolve-value-query/resolve-value-query-executor.js +1 -1
- package/queries/query.d.ts +9 -1
- package/queries/query.js +2 -0
- package/r-bridge/lang-4.x/ast/model/model.d.ts +3 -0
- package/r-bridge/lang-4.x/ast/model/model.js +3 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-access.d.ts +16 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-access.js +2 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-argument.d.ts +16 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-argument.js +2 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-binary-op.d.ts +16 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-binary-op.js +2 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-break.d.ts +15 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-break.js +2 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-comment.d.ts +15 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-comment.js +2 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-expression-list.d.ts +16 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-expression-list.js +2 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-for-loop.d.ts +16 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-for-loop.js +2 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-function-call.d.ts +16 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-function-call.js +2 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-function-definition.d.ts +21 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-function-definition.js +16 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-if-then-else.d.ts +16 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-if-then-else.js +2 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-line-directive.d.ts +16 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-line-directive.js +2 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-logical.d.ts +16 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-logical.js +2 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-next.d.ts +16 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-next.js +2 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-number.d.ts +16 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-number.js +2 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-parameter.d.ts +16 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-parameter.js +2 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-pipe.d.ts +16 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-pipe.js +2 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-repeat-loop.d.ts +16 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-repeat-loop.js +2 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-string.d.ts +16 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-string.js +2 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-symbol.d.ts +16 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-symbol.js +2 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-unary-op.d.ts +16 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-unary-op.js +2 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-while-loop.d.ts +16 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-while-loop.js +2 -0
- package/search/search-executor/search-generators.js +1 -1
- package/slicing/criterion/parse.d.ts +11 -10
- package/slicing/criterion/parse.js +9 -8
- package/slicing/static/static-slicer.js +24 -1
- package/util/collections/arrays.d.ts +4 -0
- package/util/collections/arrays.js +7 -0
- package/util/mermaid/dfg.js +2 -1
- package/util/version.js +1 -1
package/README.md
CHANGED
|
@@ -24,7 +24,7 @@ It offers a wide variety of features, for example:
|
|
|
24
24
|
|
|
25
25
|
```shell
|
|
26
26
|
$ docker run -it --rm eagleoutice/flowr # or npm run flowr
|
|
27
|
-
flowR repl using flowR v2.
|
|
27
|
+
flowR repl using flowR v2.10.0, R grammar v14 (tree-sitter engine)
|
|
28
28
|
R> :query @linter "read.csv(\"/root/x.txt\")"
|
|
29
29
|
```
|
|
30
30
|
|
|
@@ -35,17 +35,17 @@ It offers a wide variety of features, for example:
|
|
|
35
35
|
```text
|
|
36
36
|
Query: linter (2 ms)
|
|
37
37
|
╰ Deprecated Functions (deprecated-functions):
|
|
38
|
-
╰ Metadata: totalCalls: 0, totalFunctionDefinitions: 0, searchTimeMs:
|
|
38
|
+
╰ Metadata: totalCalls: 0, totalFunctionDefinitions: 0, searchTimeMs: 1, processTimeMs: 0
|
|
39
39
|
╰ File Path Validity (file-path-validity):
|
|
40
40
|
╰ certain:
|
|
41
41
|
╰ Path `/root/x.txt` at 1.1-23
|
|
42
|
-
╰ Metadata: totalReads: 1, totalUnknown: 0, totalWritesBeforeAlways: 0, totalValid: 0, searchTimeMs:
|
|
42
|
+
╰ Metadata: totalReads: 1, totalUnknown: 0, totalWritesBeforeAlways: 0, totalValid: 0, searchTimeMs: 0, processTimeMs: 0
|
|
43
43
|
╰ Seeded Randomness (seeded-randomness):
|
|
44
44
|
╰ Metadata: consumerCalls: 0, callsWithFunctionProducers: 0, callsWithAssignmentProducers: 0, callsWithNonConstantProducers: 0, callsWithOtherBranchProducers: 0, searchTimeMs: 0, processTimeMs: 0
|
|
45
45
|
╰ Absolute Paths (absolute-file-paths):
|
|
46
46
|
╰ certain:
|
|
47
47
|
╰ Path `/root/x.txt` at 1.1-23
|
|
48
|
-
╰ Metadata: totalConsidered: 1, totalUnknown: 0, searchTimeMs:
|
|
48
|
+
╰ Metadata: totalConsidered: 1, totalUnknown: 0, searchTimeMs: 1, processTimeMs: 0
|
|
49
49
|
╰ Unused Definitions (unused-definitions):
|
|
50
50
|
╰ Metadata: totalConsidered: 0, searchTimeMs: 0, processTimeMs: 0
|
|
51
51
|
╰ Naming Convention (naming-convention):
|
|
@@ -53,11 +53,13 @@ It offers a wide variety of features, for example:
|
|
|
53
53
|
╰ Network Functions (network-functions):
|
|
54
54
|
╰ Metadata: totalCalls: 0, totalFunctionDefinitions: 0, searchTimeMs: 0, processTimeMs: 0
|
|
55
55
|
╰ Dataframe Access Validation (dataframe-access-validation):
|
|
56
|
-
╰ Metadata: numOperations: 0, numAccesses: 0, totalAccessed: 0, searchTimeMs: 0, processTimeMs:
|
|
56
|
+
╰ Metadata: numOperations: 0, numAccesses: 0, totalAccessed: 0, searchTimeMs: 0, processTimeMs: 0
|
|
57
57
|
╰ Dead Code (dead-code):
|
|
58
58
|
╰ Metadata: consideredNodes: 5, searchTimeMs: 0, processTimeMs: 0
|
|
59
59
|
╰ Useless Loops (useless-loop):
|
|
60
60
|
╰ Metadata: numOfUselessLoops: 0, searchTimeMs: 0, processTimeMs: 0
|
|
61
|
+
╰ Problematic eval (problematic-eval):
|
|
62
|
+
╰ Metadata: searchTimeMs: 0, processTimeMs: 0
|
|
61
63
|
╰ Stop without call.=False argument (stop-call):
|
|
62
64
|
╰ Metadata: consideredNodes: 0, searchTimeMs: 0, processTimeMs: 0
|
|
63
65
|
All queries together required ≈2 ms (1ms accuracy, total 2 ms)
|
|
@@ -84,17 +86,17 @@ It offers a wide variety of features, for example:
|
|
|
84
86
|
|
|
85
87
|
Query: **linter** (2 ms)\
|
|
86
88
|
╰ **Deprecated Functions** (deprecated-functions):\
|
|
87
|
-
╰ _Metadata_: <code>totalCalls: 0, totalFunctionDefinitions: 0, searchTimeMs:
|
|
89
|
+
╰ _Metadata_: <code>totalCalls: 0, totalFunctionDefinitions: 0, searchTimeMs: 1, processTimeMs: 0</code>\
|
|
88
90
|
╰ **File Path Validity** (file-path-validity):\
|
|
89
91
|
╰ certain:\
|
|
90
92
|
╰ Path `/root/x.txt` at 1.1-23\
|
|
91
|
-
╰ _Metadata_: <code>totalReads: 1, totalUnknown: 0, totalWritesBeforeAlways: 0, totalValid: 0, searchTimeMs:
|
|
93
|
+
╰ _Metadata_: <code>totalReads: 1, totalUnknown: 0, totalWritesBeforeAlways: 0, totalValid: 0, searchTimeMs: 0, processTimeMs: 0</code>\
|
|
92
94
|
╰ **Seeded Randomness** (seeded-randomness):\
|
|
93
95
|
╰ _Metadata_: <code>consumerCalls: 0, callsWithFunctionProducers: 0, callsWithAssignmentProducers: 0, callsWithNonConstantProducers: 0, callsWithOtherBranchProducers: 0, searchTimeMs: 0, processTimeMs: 0</code>\
|
|
94
96
|
╰ **Absolute Paths** (absolute-file-paths):\
|
|
95
97
|
╰ certain:\
|
|
96
98
|
╰ Path `/root/x.txt` at 1.1-23\
|
|
97
|
-
╰ _Metadata_: <code>totalConsidered: 1, totalUnknown: 0, searchTimeMs:
|
|
99
|
+
╰ _Metadata_: <code>totalConsidered: 1, totalUnknown: 0, searchTimeMs: 1, processTimeMs: 0</code>\
|
|
98
100
|
╰ **Unused Definitions** (unused-definitions):\
|
|
99
101
|
╰ _Metadata_: <code>totalConsidered: 0, searchTimeMs: 0, processTimeMs: 0</code>\
|
|
100
102
|
╰ **Naming Convention** (naming-convention):\
|
|
@@ -102,11 +104,13 @@ It offers a wide variety of features, for example:
|
|
|
102
104
|
╰ **Network Functions** (network-functions):\
|
|
103
105
|
╰ _Metadata_: <code>totalCalls: 0, totalFunctionDefinitions: 0, searchTimeMs: 0, processTimeMs: 0</code>\
|
|
104
106
|
╰ **Dataframe Access Validation** (dataframe-access-validation):\
|
|
105
|
-
╰ _Metadata_: <code>numOperations: 0, numAccesses: 0, totalAccessed: 0, searchTimeMs: 0, processTimeMs:
|
|
107
|
+
╰ _Metadata_: <code>numOperations: 0, numAccesses: 0, totalAccessed: 0, searchTimeMs: 0, processTimeMs: 0</code>\
|
|
106
108
|
╰ **Dead Code** (dead-code):\
|
|
107
109
|
╰ _Metadata_: <code>consideredNodes: 5, searchTimeMs: 0, processTimeMs: 0</code>\
|
|
108
110
|
╰ **Useless Loops** (useless-loop):\
|
|
109
111
|
╰ _Metadata_: <code>numOfUselessLoops: 0, searchTimeMs: 0, processTimeMs: 0</code>\
|
|
112
|
+
╰ **Problematic eval** (problematic-eval):\
|
|
113
|
+
╰ _Metadata_: <code>searchTimeMs: 0, processTimeMs: 0</code>\
|
|
110
114
|
╰ **Stop without call.=False argument** (stop-call):\
|
|
111
115
|
╰ _Metadata_: <code>consideredNodes: 0, searchTimeMs: 0, processTimeMs: 0</code>\
|
|
112
116
|
_All queries together required ≈2 ms (1ms accuracy, total 2 ms)_
|
|
@@ -130,7 +134,7 @@ It offers a wide variety of features, for example:
|
|
|
130
134
|
".meta": {
|
|
131
135
|
"totalCalls": 0,
|
|
132
136
|
"totalFunctionDefinitions": 0,
|
|
133
|
-
"searchTimeMs":
|
|
137
|
+
"searchTimeMs": 1,
|
|
134
138
|
"processTimeMs": 0
|
|
135
139
|
}
|
|
136
140
|
},
|
|
@@ -153,7 +157,7 @@ It offers a wide variety of features, for example:
|
|
|
153
157
|
"totalUnknown": 0,
|
|
154
158
|
"totalWritesBeforeAlways": 0,
|
|
155
159
|
"totalValid": 0,
|
|
156
|
-
"searchTimeMs":
|
|
160
|
+
"searchTimeMs": 0,
|
|
157
161
|
"processTimeMs": 0
|
|
158
162
|
}
|
|
159
163
|
},
|
|
@@ -185,7 +189,7 @@ It offers a wide variety of features, for example:
|
|
|
185
189
|
".meta": {
|
|
186
190
|
"totalConsidered": 1,
|
|
187
191
|
"totalUnknown": 0,
|
|
188
|
-
"searchTimeMs":
|
|
192
|
+
"searchTimeMs": 1,
|
|
189
193
|
"processTimeMs": 0
|
|
190
194
|
}
|
|
191
195
|
},
|
|
@@ -222,7 +226,7 @@ It offers a wide variety of features, for example:
|
|
|
222
226
|
"numAccesses": 0,
|
|
223
227
|
"totalAccessed": 0,
|
|
224
228
|
"searchTimeMs": 0,
|
|
225
|
-
"processTimeMs":
|
|
229
|
+
"processTimeMs": 0
|
|
226
230
|
}
|
|
227
231
|
},
|
|
228
232
|
"dead-code": {
|
|
@@ -241,6 +245,13 @@ It offers a wide variety of features, for example:
|
|
|
241
245
|
"processTimeMs": 0
|
|
242
246
|
}
|
|
243
247
|
},
|
|
248
|
+
"problematic-eval": {
|
|
249
|
+
"results": [],
|
|
250
|
+
".meta": {
|
|
251
|
+
"searchTimeMs": 0,
|
|
252
|
+
"processTimeMs": 0
|
|
253
|
+
}
|
|
254
|
+
},
|
|
244
255
|
"stop-call": {
|
|
245
256
|
"results": [],
|
|
246
257
|
".meta": {
|
|
@@ -320,7 +331,7 @@ It offers a wide variety of features, for example:
|
|
|
320
331
|
|
|
321
332
|
```shell
|
|
322
333
|
$ docker run -it --rm eagleoutice/flowr # or npm run flowr
|
|
323
|
-
flowR repl using flowR v2.
|
|
334
|
+
flowR repl using flowR v2.10.0, R grammar v14 (tree-sitter engine)
|
|
324
335
|
R> :query @static-slice (11@sum) file://test/testfiles/example.R
|
|
325
336
|
```
|
|
326
337
|
|
|
@@ -334,7 +345,7 @@ It offers a wide variety of features, for example:
|
|
|
334
345
|
N <- 10
|
|
335
346
|
for(i in 1:(N-1)) sum <- sum + i + w
|
|
336
347
|
sum
|
|
337
|
-
All queries together required ≈
|
|
348
|
+
All queries together required ≈2 ms (1ms accuracy, total 2 ms)
|
|
338
349
|
```
|
|
339
350
|
|
|
340
351
|
|
|
@@ -368,7 +379,7 @@ It offers a wide variety of features, for example:
|
|
|
368
379
|
|
|
369
380
|
|
|
370
381
|
* 🚀 **fast call-graph, data-, and control-flow graphs**\
|
|
371
|
-
Within just [<i><span title="This measurement is automatically fetched from the latest benchmark!">
|
|
382
|
+
Within just [<i><span title="This measurement is automatically fetched from the latest benchmark!">99.2 ms</span></i> (as of Mar 13, 2026)](https://flowr-analysis.github.io/flowr/wiki/stats/benchmark),
|
|
372
383
|
_flowR_ can analyze the data- and control-flow of the average real-world R script. See the [benchmarks](https://flowr-analysis.github.io/flowr/wiki/stats/benchmark) for more information,
|
|
373
384
|
and consult the [wiki pages](https://github.com/flowr-analysis/flowr/wiki/dataflow-graph) for more details on the [dataflow graphs](https://github.com/flowr-analysis/flowr/wiki/dataflow-graph) as well as [call graphs](https://github.com/flowr-analysis/flowr/wiki/dataflow-graph#perspectives-cg).
|
|
374
385
|
|
|
@@ -404,7 +415,7 @@ It offers a wide variety of features, for example:
|
|
|
404
415
|
|
|
405
416
|
```shell
|
|
406
417
|
$ docker run -it --rm eagleoutice/flowr # or npm run flowr
|
|
407
|
-
flowR repl using flowR v2.
|
|
418
|
+
flowR repl using flowR v2.10.0, R grammar v14 (tree-sitter engine)
|
|
408
419
|
R> :dataflow* test/testfiles/example.R
|
|
409
420
|
```
|
|
410
421
|
|
|
@@ -430,7 +441,7 @@ It offers a wide variety of features, for example:
|
|
|
430
441
|
*1.8*`"}}
|
|
431
442
|
%% No edges found for 1
|
|
432
443
|
0["`#91;RSymbol#93; sum
|
|
433
|
-
(0)
|
|
444
|
+
(0, sources: [1])
|
|
434
445
|
*1.1-3*`"]
|
|
435
446
|
2[["`#91;RBinaryOp#93; #60;#45;
|
|
436
447
|
(2)
|
|
@@ -444,7 +455,7 @@ It offers a wide variety of features, for example:
|
|
|
444
455
|
*2.12*`"}}
|
|
445
456
|
%% No edges found for 4
|
|
446
457
|
3["`#91;RSymbol#93; product
|
|
447
|
-
(3)
|
|
458
|
+
(3, sources: [4])
|
|
448
459
|
*2.1-7*`"]
|
|
449
460
|
5[["`#91;RBinaryOp#93; #60;#45;
|
|
450
461
|
(5)
|
|
@@ -455,7 +466,7 @@ It offers a wide variety of features, for example:
|
|
|
455
466
|
*3.6*`"}}
|
|
456
467
|
%% No edges found for 7
|
|
457
468
|
6["`#91;RSymbol#93; w
|
|
458
|
-
(6)
|
|
469
|
+
(6, sources: [7])
|
|
459
470
|
*3.1*`"]
|
|
460
471
|
8[["`#91;RBinaryOp#93; #60;#45;
|
|
461
472
|
(8)
|
|
@@ -466,14 +477,14 @@ It offers a wide variety of features, for example:
|
|
|
466
477
|
*4.6-7*`"}}
|
|
467
478
|
%% No edges found for 10
|
|
468
479
|
9["`#91;RSymbol#93; N
|
|
469
|
-
(9)
|
|
480
|
+
(9, sources: [10])
|
|
470
481
|
*4.1*`"]
|
|
471
482
|
11[["`#91;RBinaryOp#93; #60;#45;
|
|
472
483
|
(11)
|
|
473
484
|
*4.1-7*
|
|
474
485
|
(9, 10)`"]]
|
|
475
486
|
12["`#91;RSymbol#93; i
|
|
476
|
-
(12)
|
|
487
|
+
(12, sources: [20])
|
|
477
488
|
*6.6*`"]
|
|
478
489
|
13{{"`#91;RNumber#93; 1
|
|
479
490
|
(13)
|
|
@@ -525,7 +536,7 @@ It offers a wide variety of features, for example:
|
|
|
525
536
|
*7.10-20*
|
|
526
537
|
(26, 27)`"]]
|
|
527
538
|
23["`#91;RSymbol#93; sum
|
|
528
|
-
(23, :may:36
|
|
539
|
+
(23, :may:36+, sources: [28])
|
|
529
540
|
*7.3-5*`"]
|
|
530
541
|
29[["`#91;RBinaryOp#93; #60;#45;
|
|
531
542
|
(29, :may:36+)
|
|
@@ -542,7 +553,7 @@ It offers a wide variety of features, for example:
|
|
|
542
553
|
*8.14-24*
|
|
543
554
|
(31, 32)`"]]
|
|
544
555
|
30["`#91;RSymbol#93; product
|
|
545
|
-
(30, :may:36
|
|
556
|
+
(30, :may:36+, sources: [33])
|
|
546
557
|
*8.3-9*`"]
|
|
547
558
|
34[["`#91;RBinaryOp#93; #60;#45;
|
|
548
559
|
(34, :may:36+)
|
|
@@ -889,7 +900,8 @@ We welcome every contribution! Please check out the [developer onboarding](https
|
|
|
889
900
|
|
|
890
901
|
*flowr* is actively developed by [Florian Sihler](https://eagleoutice.github.io/portfolio/) and (since October 1st 2025) [Oliver Gerstl](https://www.linkedin.com/in/oliver-gerstl) under the
|
|
891
902
|
[GPLv3 License](LICENSE).\
|
|
892
|
-
It is partially supported by the German Research Foundation (DFG) under the grant [504226141](https://gepris.dfg.de/gepris/projekt/504226141) ("CodeInspector")
|
|
903
|
+
It is partially supported by the German Research Foundation (DFG) under the grant [504226141](https://gepris.dfg.de/gepris/projekt/504226141) ("CodeInspector")
|
|
904
|
+
and received an unrestricted gift from [Posit](https://posit.co/), the open-source data science company.
|
|
893
905
|
|
|
894
906
|
----
|
|
895
907
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { SlicingCriterion, SlicingCriteria } from '../../slicing/criterion/parse';
|
|
2
2
|
import type { NodeId } from '../../r-bridge/lang-4.x/ast/model/processing/node-id';
|
|
3
3
|
import type { ReconstructionResult } from '../../reconstruct/reconstruct';
|
|
4
4
|
import type { RParseRequestFromFile, RParseRequestFromText } from '../../r-bridge/retriever';
|
|
@@ -15,7 +15,7 @@ export type ElapsedTime = bigint;
|
|
|
15
15
|
export interface PerSliceStats {
|
|
16
16
|
measurements: Map<PerSliceMeasurements, ElapsedTime>;
|
|
17
17
|
slicingCriteria: {
|
|
18
|
-
criterion:
|
|
18
|
+
criterion: SlicingCriterion;
|
|
19
19
|
id: NodeId;
|
|
20
20
|
}[];
|
|
21
21
|
reconstructedCode: ReconstructionResult;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { SlicingCriterion, SlicingCriteria } from '../../../slicing/criterion/parse';
|
|
2
2
|
import { SliceDirection } from '../../../util/slice-direction';
|
|
3
3
|
/**
|
|
4
4
|
* Checks whether the given argument represents a slicing direction with an `f` suffix.
|
|
@@ -7,7 +7,7 @@ export declare function sliceDirectionParser(argument: string): SliceDirection;
|
|
|
7
7
|
/**
|
|
8
8
|
* Parses a single slicing criterion from the given argument.
|
|
9
9
|
*/
|
|
10
|
-
export declare function sliceCriterionParser(argument: string | undefined):
|
|
10
|
+
export declare function sliceCriterionParser(argument: string | undefined): SlicingCriterion | undefined;
|
|
11
11
|
/**
|
|
12
12
|
* Parses multiple slicing criteria from the given argument.
|
|
13
13
|
*/
|
package/config.d.ts
CHANGED
|
@@ -159,6 +159,10 @@ export interface FlowrConfig extends MergeableRecord {
|
|
|
159
159
|
* The maximum number of iterations to perform on a single function call during slicing
|
|
160
160
|
*/
|
|
161
161
|
readonly threshold?: number;
|
|
162
|
+
/**
|
|
163
|
+
* If set, the slicer will gain an additional post-pass
|
|
164
|
+
*/
|
|
165
|
+
readonly autoExtend?: boolean;
|
|
162
166
|
};
|
|
163
167
|
};
|
|
164
168
|
/**
|
package/config.js
CHANGED
|
@@ -93,7 +93,8 @@ exports.FlowrConfig = {
|
|
|
93
93
|
dataflowExtractors: undefined
|
|
94
94
|
},
|
|
95
95
|
slicer: {
|
|
96
|
-
threshold: 50
|
|
96
|
+
threshold: 50,
|
|
97
|
+
autoExtend: false
|
|
97
98
|
}
|
|
98
99
|
},
|
|
99
100
|
abstractInterpretation: {
|
|
@@ -153,7 +154,8 @@ exports.FlowrConfig = {
|
|
|
153
154
|
applyReplacements: joi_1.default.array().items(joi_1.default.object()).description('Provide name replacements for loaded files')
|
|
154
155
|
}).optional().description('If lax source calls are active, flowR searches for sourced files much more freely, based on the configurations you give it. This option is only in effect if `ignoreSourceCalls` is set to false.'),
|
|
155
156
|
slicer: joi_1.default.object({
|
|
156
|
-
threshold: joi_1.default.number().optional().description('The maximum number of iterations to perform on a single function call during slicing.')
|
|
157
|
+
threshold: joi_1.default.number().optional().description('The maximum number of iterations to perform on a single function call during slicing.'),
|
|
158
|
+
autoExtend: joi_1.default.boolean().optional().description('If set, the slicer will gain an additional post-pass.')
|
|
157
159
|
}).optional().description('The configuration for the slicer.')
|
|
158
160
|
}).description('How to resolve constants, constraints, cells, ...'),
|
|
159
161
|
abstractInterpretation: joi_1.default.object({
|
|
@@ -250,7 +252,7 @@ exports.FlowrConfig = {
|
|
|
250
252
|
*/
|
|
251
253
|
setInConfigInPlace(config, key, value) {
|
|
252
254
|
object_path_1.default.set(config, key, value);
|
|
253
|
-
}
|
|
255
|
+
},
|
|
254
256
|
};
|
|
255
257
|
function loadConfigFromFile(configFile, workingDirectory) {
|
|
256
258
|
if (configFile !== undefined) {
|
|
@@ -39,6 +39,10 @@ export declare const Identifier: {
|
|
|
39
39
|
* Please note that for `internal` to count, a namespace must be provided!
|
|
40
40
|
*/
|
|
41
41
|
readonly make: (this: void, name: BrandedIdentifier, namespace?: BrandedNamespace, internal?: boolean) => Identifier;
|
|
42
|
+
/**
|
|
43
|
+
* Verify whether an unknown element has a valid identifier shape!
|
|
44
|
+
*/
|
|
45
|
+
readonly is: (this: void, id: unknown) => id is Identifier;
|
|
42
46
|
/**
|
|
43
47
|
* Parse an identifier from its string representation,
|
|
44
48
|
* Please note, that in R if one writes `"pkg::a"` this refers to a symbol named `pkg::a` and NOT to the namespaced identifier `a` in package `pkg`.
|
|
@@ -33,6 +33,23 @@ exports.Identifier = {
|
|
|
33
33
|
return name;
|
|
34
34
|
}
|
|
35
35
|
},
|
|
36
|
+
/**
|
|
37
|
+
* Verify whether an unknown element has a valid identifier shape!
|
|
38
|
+
*/
|
|
39
|
+
is(id) {
|
|
40
|
+
if (typeof id === 'string') {
|
|
41
|
+
return true;
|
|
42
|
+
}
|
|
43
|
+
if (Array.isArray(id)) {
|
|
44
|
+
if (id.length === 2) {
|
|
45
|
+
return typeof id[0] === 'string' && typeof id[1] === 'string';
|
|
46
|
+
}
|
|
47
|
+
else if (id.length === 3) {
|
|
48
|
+
return typeof id[0] === 'string' && typeof id[1] === 'string' && typeof id[2] === 'boolean';
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return false;
|
|
52
|
+
},
|
|
36
53
|
/**
|
|
37
54
|
* Parse an identifier from its string representation,
|
|
38
55
|
* Please note, that in R if one writes `"pkg::a"` this refers to a symbol named `pkg::a` and NOT to the namespaced identifier `a` in package `pkg`.
|
|
@@ -24,10 +24,6 @@ export declare const CallGraph: {
|
|
|
24
24
|
* Extracts the sub call graph from the given call graph, starting from the given entry points.
|
|
25
25
|
*/
|
|
26
26
|
readonly computeSubCallGraph: (this: void, graph: CallGraph, entryPoints: Set<NodeId>) => CallGraph;
|
|
27
|
-
/**
|
|
28
|
-
* Determines whether there is a path from `from` to `to` in the given graph (via any edge type, only respecting direction)
|
|
29
|
-
*/
|
|
30
|
-
readonly reaches: (this: void, from: NodeId, to: NodeId, graph: DataflowGraph, knownReachability?: DefaultMap<NodeId, Set<NodeId>>) => boolean;
|
|
31
27
|
/**
|
|
32
28
|
* Reduces the call graph by dropping all transitive edges.
|
|
33
29
|
*/
|
|
@@ -53,8 +49,9 @@ export declare const CallGraph: {
|
|
|
53
49
|
readonly convert: typeof import("./quads").df2quads;
|
|
54
50
|
};
|
|
55
51
|
};
|
|
56
|
-
readonly diffGraphs: (this: void, left: import("../../util/diff-graph").NamedGraph
|
|
57
|
-
readonly invertGraph: (this: void, graph:
|
|
58
|
-
readonly resolveGraphCriteria: (graph:
|
|
52
|
+
readonly diffGraphs: <G extends DataflowGraph>(this: void, left: import("../../util/diff-graph").NamedGraph<G>, right: import("../../util/diff-graph").NamedGraph<G>, config?: Partial<import("../../util/diff").GenericDiffConfiguration>) => import("../../util/diff-graph").GraphDifferenceReport;
|
|
53
|
+
readonly invertGraph: <G extends DataflowGraph>(this: void, graph: G, cleanEnv: REnvironmentInformation) => G;
|
|
54
|
+
readonly resolveGraphCriteria: <G extends DataflowGraph>(graph: G, ctx: import("../../project/context/flowr-analyzer-context").ReadOnlyFlowrAnalyzerContext, idMap?: import("../../r-bridge/lang-4.x/ast/model/processing/decorate").AstIdMap) => G;
|
|
55
|
+
readonly reaches: <G extends DataflowGraph>(this: void, from: NodeId, to: NodeId, graph: G, knownReachability?: DefaultMap<NodeId, Set<NodeId>>) => boolean;
|
|
59
56
|
readonly name: "CallGraph";
|
|
60
57
|
};
|
|
@@ -189,28 +189,6 @@ exports.CallGraph = {
|
|
|
189
189
|
}
|
|
190
190
|
return result;
|
|
191
191
|
},
|
|
192
|
-
/**
|
|
193
|
-
* Determines whether there is a path from `from` to `to` in the given graph (via any edge type, only respecting direction)
|
|
194
|
-
*/
|
|
195
|
-
reaches(from, to, graph, knownReachability = new defaultmap_1.DefaultMap(() => new Set())) {
|
|
196
|
-
const visited = new Set();
|
|
197
|
-
const toVisit = [from];
|
|
198
|
-
while (toVisit.length > 0) {
|
|
199
|
-
const currentId = toVisit.pop();
|
|
200
|
-
if (visited.has(currentId)) {
|
|
201
|
-
continue;
|
|
202
|
-
}
|
|
203
|
-
if (currentId === to || knownReachability.get(currentId).has(to)) {
|
|
204
|
-
knownReachability.get(from).add(to);
|
|
205
|
-
return true;
|
|
206
|
-
}
|
|
207
|
-
visited.add(currentId);
|
|
208
|
-
for (const [tar] of graph.outgoingEdges(currentId) ?? []) {
|
|
209
|
-
toVisit.push(tar);
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
return false;
|
|
213
|
-
},
|
|
214
192
|
/**
|
|
215
193
|
* Reduces the call graph by dropping all transitive edges.
|
|
216
194
|
*/
|
|
@@ -41,7 +41,6 @@ export declare const Dataflow: {
|
|
|
41
41
|
*/
|
|
42
42
|
readonly callGraph: {
|
|
43
43
|
readonly computeSubCallGraph: (this: void, graph: CallGraph, entryPoints: Set<NodeId>) => CallGraph;
|
|
44
|
-
readonly reaches: (this: void, from: NodeId, to: NodeId, graph: DataflowGraph, knownReachability?: import("../../util/collections/defaultmap").DefaultMap<NodeId, Set<NodeId>>) => boolean;
|
|
45
44
|
readonly dropTransitiveEdges: (this: void, graph: CallGraph) => CallGraph;
|
|
46
45
|
readonly compute: (this: void, graph: DataflowGraph) => CallGraph;
|
|
47
46
|
readonly visualize: {
|
|
@@ -58,9 +57,10 @@ export declare const Dataflow: {
|
|
|
58
57
|
readonly convert: typeof import("./quads").df2quads;
|
|
59
58
|
};
|
|
60
59
|
};
|
|
61
|
-
readonly diffGraphs: (this: void, left: import("../../util/diff-graph").NamedGraph
|
|
62
|
-
readonly invertGraph: (this: void, graph:
|
|
63
|
-
readonly resolveGraphCriteria: (graph:
|
|
60
|
+
readonly diffGraphs: <G extends DataflowGraph>(this: void, left: import("../../util/diff-graph").NamedGraph<G>, right: import("../../util/diff-graph").NamedGraph<G>, config?: Partial<import("../../util/diff").GenericDiffConfiguration>) => import("../../util/diff-graph").GraphDifferenceReport;
|
|
61
|
+
readonly invertGraph: <G extends DataflowGraph>(this: void, graph: G, cleanEnv: REnvironmentInformation) => G;
|
|
62
|
+
readonly resolveGraphCriteria: <G extends DataflowGraph>(graph: G, ctx: import("../../project/context/flowr-analyzer-context").ReadOnlyFlowrAnalyzerContext, idMap?: import("../../r-bridge/lang-4.x/ast/model/processing/decorate").AstIdMap) => G;
|
|
63
|
+
readonly reaches: <G extends DataflowGraph>(this: void, from: NodeId, to: NodeId, graph: G, knownReachability?: import("../../util/collections/defaultmap").DefaultMap<NodeId, Set<NodeId>>) => boolean;
|
|
64
64
|
readonly name: "CallGraph";
|
|
65
65
|
};
|
|
66
66
|
};
|
|
@@ -87,7 +87,7 @@ export declare const Dataflow: {
|
|
|
87
87
|
* @param select - the ids to select in the reduced graph
|
|
88
88
|
* @param includeMissingTargets - if set to true, this will include edges which target vertices that are not selected!
|
|
89
89
|
*/
|
|
90
|
-
readonly reduceGraph: (this: void, graph:
|
|
90
|
+
readonly reduceGraph: <G extends DataflowGraph>(this: void, graph: G, select: ReadonlySet<NodeId>, includeMissingTargets?: boolean) => G;
|
|
91
91
|
/**
|
|
92
92
|
* Given the id of a vertex (usually a variable use),
|
|
93
93
|
* this returns a reachable provenance set by calculating a non-interprocedural and non-context sensitive backward slice, but stopping at the given ids!
|
|
@@ -120,9 +120,10 @@ export declare const Dataflow: {
|
|
|
120
120
|
readonly convert: typeof import("./quads").df2quads;
|
|
121
121
|
};
|
|
122
122
|
};
|
|
123
|
-
readonly diffGraphs: (this: void, left: import("../../util/diff-graph").NamedGraph
|
|
124
|
-
readonly invertGraph: (this: void, graph:
|
|
125
|
-
readonly resolveGraphCriteria: (graph:
|
|
123
|
+
readonly diffGraphs: <G extends DataflowGraph>(this: void, left: import("../../util/diff-graph").NamedGraph<G>, right: import("../../util/diff-graph").NamedGraph<G>, config?: Partial<import("../../util/diff").GenericDiffConfiguration>) => import("../../util/diff-graph").GraphDifferenceReport;
|
|
124
|
+
readonly invertGraph: <G extends DataflowGraph>(this: void, graph: G, cleanEnv: REnvironmentInformation) => G;
|
|
125
|
+
readonly resolveGraphCriteria: <G extends DataflowGraph>(graph: G, ctx: import("../../project/context/flowr-analyzer-context").ReadOnlyFlowrAnalyzerContext, idMap?: import("../../r-bridge/lang-4.x/ast/model/processing/decorate").AstIdMap) => G;
|
|
126
|
+
readonly reaches: <G extends DataflowGraph>(this: void, from: NodeId, to: NodeId, graph: G, knownReachability?: import("../../util/collections/defaultmap").DefaultMap<NodeId, Set<NodeId>>) => boolean;
|
|
126
127
|
readonly name: "Dataflow";
|
|
127
128
|
/**
|
|
128
129
|
* Maps to flowR's main graph object to store and manipulate the dataflow graph
|
|
@@ -102,18 +102,25 @@ exports.Dataflow = {
|
|
|
102
102
|
provenance(id, graph, consider) {
|
|
103
103
|
const queue = [id];
|
|
104
104
|
const visited = new Set();
|
|
105
|
-
const followEdges = edge_1.EdgeType.Calls | edge_1.EdgeType.Reads | edge_1.EdgeType.Returns | edge_1.EdgeType.DefinedBy | edge_1.EdgeType.DefinedByOnCall;
|
|
105
|
+
const followEdges = edge_1.EdgeType.Calls | edge_1.EdgeType.Reads | edge_1.EdgeType.Returns | edge_1.EdgeType.Argument | edge_1.EdgeType.DefinedBy | edge_1.EdgeType.DefinedByOnCall;
|
|
106
106
|
while (queue.length > 0) {
|
|
107
107
|
const nodeId = queue.pop();
|
|
108
108
|
if (nodeId === undefined || visited.has(nodeId) || (consider && !consider.has(nodeId))) {
|
|
109
109
|
continue;
|
|
110
110
|
}
|
|
111
111
|
visited.add(nodeId);
|
|
112
|
-
|
|
112
|
+
const vtx = graph.get(nodeId);
|
|
113
|
+
if (vtx === undefined) {
|
|
114
|
+
continue;
|
|
115
|
+
}
|
|
116
|
+
for (const [to, types] of vtx[1]) {
|
|
113
117
|
if (edge_1.DfEdge.includesType(types, followEdges)) {
|
|
114
118
|
queue.push(to);
|
|
115
119
|
}
|
|
116
120
|
}
|
|
121
|
+
for (const cd of vtx[0].cds ?? []) {
|
|
122
|
+
queue.push(cd.id);
|
|
123
|
+
}
|
|
117
124
|
}
|
|
118
125
|
return visited;
|
|
119
126
|
},
|
|
@@ -7,6 +7,7 @@ import type { REnvironmentInformation } from '../environments/environment';
|
|
|
7
7
|
import type { ReadOnlyFlowrAnalyzerContext } from '../../project/context/flowr-analyzer-context';
|
|
8
8
|
import type { AstIdMap } from '../../r-bridge/lang-4.x/ast/model/processing/decorate';
|
|
9
9
|
import type { NodeId } from '../../r-bridge/lang-4.x/ast/model/processing/node-id';
|
|
10
|
+
import { DefaultMap } from '../../util/collections/defaultmap';
|
|
10
11
|
/**
|
|
11
12
|
* The underlying functions which work for any graph* like view
|
|
12
13
|
* **Please do not use this object directly but use the helpers**
|
|
@@ -19,7 +20,7 @@ export declare const GraphHelper: {
|
|
|
19
20
|
/**
|
|
20
21
|
* Mermaid rendering helper for dataflow graphs
|
|
21
22
|
* - {@link DataflowMermaid.url}, {@link DataflowMermaid.raw} - to render the graph as a mermaid graph (e.g., in markdown or the mermaid live editor)
|
|
22
|
-
* - {@link DataflowMermaid.convert} - for the
|
|
23
|
+
* - {@link DataflowMermaid.convert} - for the underlying transformation
|
|
23
24
|
* @see {@link DataflowMermaid}
|
|
24
25
|
*/
|
|
25
26
|
readonly mermaid: {
|
|
@@ -40,16 +41,20 @@ export declare const GraphHelper: {
|
|
|
40
41
|
* If you simply want to check whether they equal, use {@link GraphDifferenceReport#isEqual|`<result>.isEqual()`}.
|
|
41
42
|
* @see {@link diffOfControlFlowGraphs} - for control flow graphs
|
|
42
43
|
*/
|
|
43
|
-
readonly diffGraphs: (this: void, left: NamedGraph
|
|
44
|
+
readonly diffGraphs: <G extends DataflowGraph>(this: void, left: NamedGraph<G>, right: NamedGraph<G>, config?: Partial<GenericDiffConfiguration>) => GraphDifferenceReport;
|
|
44
45
|
/**
|
|
45
46
|
* Inverts the given dataflow graph by reversing all edges.
|
|
46
47
|
*/
|
|
47
|
-
readonly invertGraph: (this: void, graph:
|
|
48
|
+
readonly invertGraph: <G extends DataflowGraph>(this: void, graph: G, cleanEnv: REnvironmentInformation) => G;
|
|
48
49
|
/**
|
|
49
50
|
* Resolves the dataflow graph ids from slicing criterion form to ids.
|
|
50
51
|
* This returns a **new** graph with the resolved ids.
|
|
51
52
|
* The main use-case for this is testing - if you do not know/want to fix the specific id,
|
|
52
53
|
* you can use, e.g. `2@x` as a placeholder for the first x in the second line!
|
|
53
54
|
*/
|
|
54
|
-
readonly resolveGraphCriteria: (graph:
|
|
55
|
+
readonly resolveGraphCriteria: <G extends DataflowGraph>(graph: G, ctx: ReadOnlyFlowrAnalyzerContext, idMap?: AstIdMap) => G;
|
|
56
|
+
/**
|
|
57
|
+
* Determines whether there is a path from `from` to `to` in the given graph (via any edge type, only respecting direction)
|
|
58
|
+
*/
|
|
59
|
+
readonly reaches: <G extends DataflowGraph>(this: void, from: NodeId, to: NodeId, graph: G, knownReachability?: DefaultMap<NodeId, Set<NodeId>>) => boolean;
|
|
55
60
|
};
|
|
@@ -9,6 +9,7 @@ const graph_1 = require("./graph");
|
|
|
9
9
|
const assert_1 = require("../../util/assert");
|
|
10
10
|
const parse_1 = require("../../slicing/criterion/parse");
|
|
11
11
|
const edge_1 = require("./edge");
|
|
12
|
+
const defaultmap_1 = require("../../util/collections/defaultmap");
|
|
12
13
|
/**
|
|
13
14
|
* The underlying functions which work for any graph* like view
|
|
14
15
|
* **Please do not use this object directly but use the helpers**
|
|
@@ -21,7 +22,7 @@ exports.GraphHelper = {
|
|
|
21
22
|
/**
|
|
22
23
|
* Mermaid rendering helper for dataflow graphs
|
|
23
24
|
* - {@link DataflowMermaid.url}, {@link DataflowMermaid.raw} - to render the graph as a mermaid graph (e.g., in markdown or the mermaid live editor)
|
|
24
|
-
* - {@link DataflowMermaid.convert} - for the
|
|
25
|
+
* - {@link DataflowMermaid.convert} - for the underlying transformation
|
|
25
26
|
* @see {@link DataflowMermaid}
|
|
26
27
|
*/
|
|
27
28
|
mermaid: dfg_1.DataflowMermaid,
|
|
@@ -70,7 +71,7 @@ exports.GraphHelper = {
|
|
|
70
71
|
if (cached !== undefined) {
|
|
71
72
|
return cached;
|
|
72
73
|
}
|
|
73
|
-
const resolved = parse_1.
|
|
74
|
+
const resolved = parse_1.SlicingCriterion.tryParse(id, resolveMap) ?? id;
|
|
74
75
|
cache.set(id, resolved);
|
|
75
76
|
return resolved;
|
|
76
77
|
};
|
|
@@ -100,6 +101,28 @@ exports.GraphHelper = {
|
|
|
100
101
|
}
|
|
101
102
|
}
|
|
102
103
|
return resultGraph;
|
|
103
|
-
}
|
|
104
|
+
},
|
|
105
|
+
/**
|
|
106
|
+
* Determines whether there is a path from `from` to `to` in the given graph (via any edge type, only respecting direction)
|
|
107
|
+
*/
|
|
108
|
+
reaches(from, to, graph, knownReachability = new defaultmap_1.DefaultMap(() => new Set())) {
|
|
109
|
+
const visited = new Set();
|
|
110
|
+
const toVisit = [from];
|
|
111
|
+
while (toVisit.length > 0) {
|
|
112
|
+
const currentId = toVisit.pop();
|
|
113
|
+
if (visited.has(currentId)) {
|
|
114
|
+
continue;
|
|
115
|
+
}
|
|
116
|
+
if (currentId === to || knownReachability.get(currentId).has(to)) {
|
|
117
|
+
knownReachability.get(from).add(to);
|
|
118
|
+
return true;
|
|
119
|
+
}
|
|
120
|
+
visited.add(currentId);
|
|
121
|
+
for (const [tar] of graph.outgoingEdges(currentId) ?? []) {
|
|
122
|
+
toVisit.push(tar);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
return false;
|
|
126
|
+
},
|
|
104
127
|
};
|
|
105
128
|
//# sourceMappingURL=graph-helper.js.map
|
|
@@ -25,6 +25,7 @@ export type DataflowFunctionFlowInformation = Omit<DataflowInformation, 'graph'
|
|
|
25
25
|
*/
|
|
26
26
|
export interface NamedFunctionArgument extends IdentifierReference {
|
|
27
27
|
readonly name: string;
|
|
28
|
+
readonly valueId: NodeId | undefined;
|
|
28
29
|
}
|
|
29
30
|
/**
|
|
30
31
|
* A reference which does not have a name, like the references to the arguments `3` and `2` in the following:
|
|
@@ -32,7 +33,6 @@ export interface NamedFunctionArgument extends IdentifierReference {
|
|
|
32
33
|
* ```r
|
|
33
34
|
* foo(3, 2)
|
|
34
35
|
* ```
|
|
35
|
-
* @see #isPositionalArgument
|
|
36
36
|
* @see NamedFunctionArgument
|
|
37
37
|
*/
|
|
38
38
|
export interface PositionalFunctionArgument extends Omit<IdentifierReference, 'name'> {
|
|
@@ -95,12 +95,22 @@ export declare const FunctionArgument: {
|
|
|
95
95
|
* @see {@link FunctionArgument.isEmpty}
|
|
96
96
|
*/
|
|
97
97
|
readonly isNotEmpty: <T>(this: void, arg: T) => arg is Exclude<T, typeof EmptyArgument>;
|
|
98
|
+
/**
|
|
99
|
+
* Returns the id of a non-empty argument.
|
|
100
|
+
* @example
|
|
101
|
+
* ```r
|
|
102
|
+
* foo(a=3, 2) # returns the node id of either `a` or `2`
|
|
103
|
+
* ```
|
|
104
|
+
* @see {@link FunctionArgument.getReference}
|
|
105
|
+
*/
|
|
106
|
+
readonly getId: (this: void, arg: FunctionArgument) => NodeId | undefined;
|
|
98
107
|
/**
|
|
99
108
|
* Returns the reference of a non-empty argument.
|
|
100
109
|
* @example
|
|
101
110
|
* ```r
|
|
102
111
|
* foo(a=3, 2) # returns the node id of either `3` or `2`, but skips a
|
|
103
112
|
* ```
|
|
113
|
+
* @see {@link FunctionArgument.getId}
|
|
104
114
|
*/
|
|
105
115
|
readonly getReference: (this: void, arg: FunctionArgument) => NodeId | undefined;
|
|
106
116
|
/**
|
|
@@ -259,8 +269,9 @@ export declare class DataflowGraph<Vertex extends DataflowGraphVertexInfo = Data
|
|
|
259
269
|
/**
|
|
260
270
|
* Marks a vertex in the graph to be a definition
|
|
261
271
|
* @param reference - The reference to the vertex to mark as definition
|
|
272
|
+
* @param sourceIds - The id of the source vertex of the def, if available
|
|
262
273
|
*/
|
|
263
|
-
setDefinitionOfVertex(reference: IdentifierReference): void;
|
|
274
|
+
setDefinitionOfVertex(reference: IdentifierReference, sourceIds: readonly NodeId[] | undefined): void;
|
|
264
275
|
/**
|
|
265
276
|
* Marks a vertex in the graph to be a function call with the new information
|
|
266
277
|
* @param info - The information about the new function call node
|