@eagleoutice/flowr 2.10.3 → 2.10.5
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 +43 -26
- package/abstract-interpretation/absint-visitor.d.ts +17 -21
- package/abstract-interpretation/absint-visitor.js +47 -48
- package/abstract-interpretation/data-frame/dataframe-domain.d.ts +0 -3
- package/abstract-interpretation/data-frame/shape-inference.d.ts +2 -1
- package/abstract-interpretation/data-frame/shape-inference.js +5 -4
- package/abstract-interpretation/domains/abstract-domain.d.ts +17 -16
- package/abstract-interpretation/domains/abstract-domain.js +25 -27
- package/abstract-interpretation/domains/bounded-set-domain.js +1 -1
- package/abstract-interpretation/domains/multi-value-state-domain.d.ts +32 -0
- package/abstract-interpretation/domains/multi-value-state-domain.js +60 -0
- package/abstract-interpretation/domains/partial-product-domain.d.ts +43 -0
- package/abstract-interpretation/domains/partial-product-domain.js +163 -0
- package/abstract-interpretation/domains/product-domain.d.ts +2 -29
- package/abstract-interpretation/domains/product-domain.js +6 -123
- package/abstract-interpretation/domains/set-range-domain.js +3 -3
- package/abstract-interpretation/domains/set-upper-bound-domain.js +1 -1
- package/abstract-interpretation/domains/singleton-domain.js +1 -1
- package/abstract-interpretation/domains/state-abstract-domain.d.ts +13 -28
- package/abstract-interpretation/domains/state-abstract-domain.js +16 -38
- package/abstract-interpretation/domains/state-domain-like.d.ts +36 -0
- package/abstract-interpretation/domains/state-domain-like.js +3 -0
- package/cli/flowr.js +11 -1
- package/config.d.ts +7 -0
- package/config.js +22 -3
- package/control-flow/semantic-cfg-guided-visitor.d.ts +4 -0
- package/control-flow/semantic-cfg-guided-visitor.js +20 -32
- package/dataflow/environments/default-builtin-config.d.ts +10 -0
- package/dataflow/environments/default-builtin-config.js +2 -1
- package/dataflow/internal/process/functions/call/built-in/built-in-eval.d.ts +2 -0
- package/dataflow/internal/process/functions/call/built-in/built-in-eval.js +38 -21
- package/documentation/doc-readme.js +13 -2
- package/documentation/wiki-absint.d.ts +1 -2
- package/documentation/wiki-absint.js +34 -10
- package/documentation/wiki-analyzer.js +3 -4
- package/documentation/wiki-interface.js +21 -16
- package/documentation/wiki-linter.js +1 -1
- package/linter/linter-rules.d.ts +12 -12
- package/linter/linter-rules.js +2 -2
- package/linter/rules/network-functions.d.ts +1 -1
- package/linter/rules/network-functions.js +8 -2
- package/linter/rules/problematic-inputs.d.ts +43 -0
- package/linter/rules/problematic-inputs.js +110 -0
- package/linter/rules/seeded-randomness.d.ts +1 -1
- package/linter/rules/seeded-randomness.js +8 -1
- package/package.json +4 -4
- package/project/flowr-analyzer-builder.d.ts +6 -3
- package/project/flowr-analyzer-builder.js +12 -5
- package/project/plugins/file-plugins/files/flowr-rmarkdown-file.d.ts +4 -3
- package/project/plugins/file-plugins/files/flowr-rmarkdown-file.js +17 -4
- package/project/plugins/flowr-analyzer-plugin.d.ts +1 -1
- package/project/plugins/flowr-analyzer-plugin.js +1 -1
- package/queries/catalog/call-context-query/call-context-query-executor.js +2 -2
- package/queries/catalog/call-context-query/call-context-query-format.d.ts +1 -1
- package/queries/catalog/call-context-query/call-context-query-format.js +1 -2
- package/queries/catalog/dependencies-query/function-info/read-functions.js +6 -0
- package/queries/catalog/dependencies-query/function-info/write-functions.js +7 -0
- package/queries/catalog/input-sources-query/input-source-functions.d.ts +6 -0
- package/queries/catalog/input-sources-query/input-source-functions.js +50 -0
- package/queries/catalog/input-sources-query/input-sources-query-executor.d.ts +1 -1
- package/queries/catalog/input-sources-query/input-sources-query-executor.js +19 -31
- package/queries/catalog/input-sources-query/input-sources-query-format.d.ts +2 -1
- package/queries/catalog/input-sources-query/input-sources-query-format.js +26 -8
- package/queries/catalog/input-sources-query/simple-input-classifier.d.ts +33 -28
- package/queries/catalog/input-sources-query/simple-input-classifier.js +192 -99
- package/r-bridge/lang-4.x/ast/model/model.d.ts +4 -4
- package/r-bridge/lang-4.x/ast/model/nodes/r-access.d.ts +3 -3
- package/r-bridge/lang-4.x/ast/model/nodes/r-argument.d.ts +3 -3
- package/r-bridge/lang-4.x/ast/model/nodes/r-binary-op.d.ts +3 -3
- package/r-bridge/lang-4.x/ast/model/nodes/r-break.d.ts +3 -3
- package/r-bridge/lang-4.x/ast/model/nodes/r-comment.d.ts +3 -3
- package/r-bridge/lang-4.x/ast/model/nodes/r-expression-list.d.ts +3 -3
- package/r-bridge/lang-4.x/ast/model/nodes/r-for-loop.d.ts +3 -3
- package/r-bridge/lang-4.x/ast/model/nodes/r-function-call.d.ts +3 -3
- package/r-bridge/lang-4.x/ast/model/nodes/r-function-definition.d.ts +3 -3
- package/r-bridge/lang-4.x/ast/model/nodes/r-if-then-else.d.ts +3 -3
- package/r-bridge/lang-4.x/ast/model/nodes/r-line-directive.d.ts +3 -3
- package/r-bridge/lang-4.x/ast/model/nodes/r-logical.d.ts +3 -3
- package/r-bridge/lang-4.x/ast/model/nodes/r-next.d.ts +3 -3
- package/r-bridge/lang-4.x/ast/model/nodes/r-number.d.ts +3 -3
- package/r-bridge/lang-4.x/ast/model/nodes/r-parameter.d.ts +3 -3
- package/r-bridge/lang-4.x/ast/model/nodes/r-pipe.d.ts +3 -3
- package/r-bridge/lang-4.x/ast/model/nodes/r-repeat-loop.d.ts +3 -3
- package/r-bridge/lang-4.x/ast/model/nodes/r-string.d.ts +3 -3
- package/r-bridge/lang-4.x/ast/model/nodes/r-symbol.d.ts +3 -3
- package/r-bridge/lang-4.x/ast/model/nodes/r-unary-op.d.ts +3 -3
- package/r-bridge/lang-4.x/ast/model/nodes/r-while-loop.d.ts +3 -3
- package/util/record.d.ts +18 -3
- package/util/record.js +22 -1
- package/util/version.js +1 -1
- package/linter/rules/problematic-eval.d.ts +0 -44
- package/linter/rules/problematic-eval.js +0 -83
- package/project/plugins/flowr-analyzer-plugin-defaults.d.ts +0 -5
- package/project/plugins/flowr-analyzer-plugin-defaults.js +0 -37
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.10.
|
|
27
|
+
flowR repl using flowR v2.10.4, R grammar v14 (tree-sitter engine)
|
|
28
28
|
R> :query @linter "read.csv(\"/root/x.txt\")"
|
|
29
29
|
```
|
|
30
30
|
|
|
@@ -39,13 +39,13 @@ It offers a wide variety of features, for example:
|
|
|
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,18 +53,18 @@ 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
|
|
61
|
+
╰ Problematic inputs (problematic-inputs):
|
|
62
62
|
╰ Metadata: searchTimeMs: 0, processTimeMs: 0
|
|
63
63
|
╰ Stop without call.=False argument (stop-call):
|
|
64
|
-
╰ Metadata: consideredNodes: 0, searchTimeMs:
|
|
64
|
+
╰ Metadata: consideredNodes: 0, searchTimeMs: 1, processTimeMs: 0
|
|
65
65
|
╰ Roxygen Arguments (roxygen-arguments):
|
|
66
66
|
╰ Metadata: searchTimeMs: 0, processTimeMs: 0
|
|
67
|
-
All queries together required ≈2 ms (1ms accuracy, total
|
|
67
|
+
All queries together required ≈2 ms (1ms accuracy, total 3 ms)
|
|
68
68
|
```
|
|
69
69
|
|
|
70
70
|
|
|
@@ -86,7 +86,7 @@ It offers a wide variety of features, for example:
|
|
|
86
86
|
|
|
87
87
|
_Results (prettified and summarized):_
|
|
88
88
|
|
|
89
|
-
Query: **linter** (
|
|
89
|
+
Query: **linter** (2 ms)\
|
|
90
90
|
╰ **Deprecated Functions** (deprecated-functions):\
|
|
91
91
|
╰ _Metadata_: <code>totalCalls: 0, totalFunctionDefinitions: 0, searchTimeMs: 1, processTimeMs: 0</code>\
|
|
92
92
|
╰ **File Path Validity** (file-path-validity):\
|
|
@@ -94,11 +94,11 @@ It offers a wide variety of features, for example:
|
|
|
94
94
|
╰ Path `/root/x.txt` at 1.1-23\
|
|
95
95
|
╰ _Metadata_: <code>totalReads: 1, totalUnknown: 0, totalWritesBeforeAlways: 0, totalValid: 0, searchTimeMs: 0, processTimeMs: 0</code>\
|
|
96
96
|
╰ **Seeded Randomness** (seeded-randomness):\
|
|
97
|
-
╰ _Metadata_: <code>consumerCalls: 0, callsWithFunctionProducers: 0, callsWithAssignmentProducers: 0, callsWithNonConstantProducers: 0, callsWithOtherBranchProducers: 0, searchTimeMs:
|
|
97
|
+
╰ _Metadata_: <code>consumerCalls: 0, callsWithFunctionProducers: 0, callsWithAssignmentProducers: 0, callsWithNonConstantProducers: 0, callsWithOtherBranchProducers: 0, searchTimeMs: 0, processTimeMs: 0</code>\
|
|
98
98
|
╰ **Absolute Paths** (absolute-file-paths):\
|
|
99
99
|
╰ certain:\
|
|
100
100
|
╰ Path `/root/x.txt` at 1.1-23\
|
|
101
|
-
╰ _Metadata_: <code>totalConsidered: 1, totalUnknown: 0, searchTimeMs:
|
|
101
|
+
╰ _Metadata_: <code>totalConsidered: 1, totalUnknown: 0, searchTimeMs: 1, processTimeMs: 0</code>\
|
|
102
102
|
╰ **Unused Definitions** (unused-definitions):\
|
|
103
103
|
╰ _Metadata_: <code>totalConsidered: 0, searchTimeMs: 0, processTimeMs: 0</code>\
|
|
104
104
|
╰ **Naming Convention** (naming-convention):\
|
|
@@ -108,20 +108,20 @@ It offers a wide variety of features, for example:
|
|
|
108
108
|
╰ **Dataframe Access Validation** (dataframe-access-validation):\
|
|
109
109
|
╰ _Metadata_: <code>numOperations: 0, numAccesses: 0, totalAccessed: 0, searchTimeMs: 0, processTimeMs: 0</code>\
|
|
110
110
|
╰ **Dead Code** (dead-code):\
|
|
111
|
-
╰ _Metadata_: <code>consideredNodes: 5, searchTimeMs:
|
|
111
|
+
╰ _Metadata_: <code>consideredNodes: 5, searchTimeMs: 0, processTimeMs: 0</code>\
|
|
112
112
|
╰ **Useless Loops** (useless-loop):\
|
|
113
113
|
╰ _Metadata_: <code>numOfUselessLoops: 0, searchTimeMs: 0, processTimeMs: 0</code>\
|
|
114
|
-
╰ **Problematic
|
|
114
|
+
╰ **Problematic inputs** (problematic-inputs):\
|
|
115
115
|
╰ _Metadata_: <code>searchTimeMs: 0, processTimeMs: 0</code>\
|
|
116
116
|
╰ **Stop without call.=False argument** (stop-call):\
|
|
117
117
|
╰ _Metadata_: <code>consideredNodes: 0, searchTimeMs: 0, processTimeMs: 0</code>\
|
|
118
118
|
╰ **Roxygen Arguments** (roxygen-arguments):\
|
|
119
119
|
╰ _Metadata_: <code>searchTimeMs: 0, processTimeMs: 0</code>\
|
|
120
|
-
_All queries together required ≈
|
|
120
|
+
_All queries together required ≈2 ms (1ms accuracy, total 2 ms)_
|
|
121
121
|
|
|
122
122
|
<details> <summary style="color:gray">Show Detailed Results as Json</summary>
|
|
123
123
|
|
|
124
|
-
The analysis required _2.
|
|
124
|
+
The analysis required _2.4 ms_ (including parsing and normalization and the query) within the generation environment.
|
|
125
125
|
|
|
126
126
|
In general, the JSON contains the Ids of the nodes in question as they are present in the normalized AST or the dataflow graph of flowR.
|
|
127
127
|
Please consult the [Interface](https://github.com/flowr-analysis/flowr/wiki/Interface) wiki page for more information on how to get those.
|
|
@@ -173,7 +173,7 @@ It offers a wide variety of features, for example:
|
|
|
173
173
|
"callsWithAssignmentProducers": 0,
|
|
174
174
|
"callsWithNonConstantProducers": 0,
|
|
175
175
|
"callsWithOtherBranchProducers": 0,
|
|
176
|
-
"searchTimeMs":
|
|
176
|
+
"searchTimeMs": 0,
|
|
177
177
|
"processTimeMs": 0
|
|
178
178
|
}
|
|
179
179
|
},
|
|
@@ -193,7 +193,7 @@ It offers a wide variety of features, for example:
|
|
|
193
193
|
".meta": {
|
|
194
194
|
"totalConsidered": 1,
|
|
195
195
|
"totalUnknown": 0,
|
|
196
|
-
"searchTimeMs":
|
|
196
|
+
"searchTimeMs": 1,
|
|
197
197
|
"processTimeMs": 0
|
|
198
198
|
}
|
|
199
199
|
},
|
|
@@ -237,7 +237,7 @@ It offers a wide variety of features, for example:
|
|
|
237
237
|
"results": [],
|
|
238
238
|
".meta": {
|
|
239
239
|
"consideredNodes": 5,
|
|
240
|
-
"searchTimeMs":
|
|
240
|
+
"searchTimeMs": 0,
|
|
241
241
|
"processTimeMs": 0
|
|
242
242
|
}
|
|
243
243
|
},
|
|
@@ -249,7 +249,7 @@ It offers a wide variety of features, for example:
|
|
|
249
249
|
"processTimeMs": 0
|
|
250
250
|
}
|
|
251
251
|
},
|
|
252
|
-
"problematic-
|
|
252
|
+
"problematic-inputs": {
|
|
253
253
|
"results": [],
|
|
254
254
|
".meta": {
|
|
255
255
|
"searchTimeMs": 0,
|
|
@@ -273,11 +273,11 @@ It offers a wide variety of features, for example:
|
|
|
273
273
|
}
|
|
274
274
|
},
|
|
275
275
|
".meta": {
|
|
276
|
-
"timing":
|
|
276
|
+
"timing": 2
|
|
277
277
|
}
|
|
278
278
|
},
|
|
279
279
|
".meta": {
|
|
280
|
-
"timing":
|
|
280
|
+
"timing": 2
|
|
281
281
|
}
|
|
282
282
|
}
|
|
283
283
|
```
|
|
@@ -342,7 +342,7 @@ It offers a wide variety of features, for example:
|
|
|
342
342
|
|
|
343
343
|
```shell
|
|
344
344
|
$ docker run -it --rm eagleoutice/flowr # or npm run flowr
|
|
345
|
-
flowR repl using flowR v2.10.
|
|
345
|
+
flowR repl using flowR v2.10.4, R grammar v14 (tree-sitter engine)
|
|
346
346
|
R> :query @static-slice (11@sum) file://test/testfiles/example.R
|
|
347
347
|
```
|
|
348
348
|
|
|
@@ -390,7 +390,7 @@ It offers a wide variety of features, for example:
|
|
|
390
390
|
|
|
391
391
|
|
|
392
392
|
* 🚀 **fast call-graph, data-, and control-flow graphs**\
|
|
393
|
-
Within just [<i><span title="This measurement is automatically fetched from the latest benchmark!">100.
|
|
393
|
+
Within just [<i><span title="This measurement is automatically fetched from the latest benchmark!">100.2 ms</span></i> (as of Apr 8, 2026)](https://flowr-analysis.github.io/flowr/wiki/stats/benchmark),
|
|
394
394
|
_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,
|
|
395
395
|
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).
|
|
396
396
|
|
|
@@ -426,7 +426,7 @@ It offers a wide variety of features, for example:
|
|
|
426
426
|
|
|
427
427
|
```shell
|
|
428
428
|
$ docker run -it --rm eagleoutice/flowr # or npm run flowr
|
|
429
|
-
flowR repl using flowR v2.10.
|
|
429
|
+
flowR repl using flowR v2.10.4, R grammar v14 (tree-sitter engine)
|
|
430
430
|
R> :dataflow* test/testfiles/example.R
|
|
431
431
|
```
|
|
432
432
|
|
|
@@ -734,7 +734,7 @@ It offers a wide variety of features, for example:
|
|
|
734
734
|
```
|
|
735
735
|
|
|
736
736
|
|
|
737
|
-
(The analysis required _1.
|
|
737
|
+
(The analysis required _1.8 ms_ (including parse and normalize, using the [tree-sitter](https://github.com/flowr-analysis/flowr/wiki/Engines) engine) within the generation environment.)
|
|
738
738
|
|
|
739
739
|
|
|
740
740
|
|
|
@@ -799,8 +799,25 @@ please check out flowR's [Zenodo archive](https://zenodo.org/doi/10.5281/zenodo.
|
|
|
799
799
|
If you are interested in the theoretical background of _flowR_,
|
|
800
800
|
please check out the following publications (if you find that a paper is missing here, please open [a new issue](https://github.com/flowr-analysis/flowr/issues/new/choose)):
|
|
801
801
|
|
|
802
|
+
* [Supporting the Comprehension of Data Analysis Scripts (FSE '25, Tool)](https://doi.org/10.1145/3803437.3806402)
|
|
803
|
+
This refers to an updated tool demonstration of the framework. Preprint available at <a href="https://doi.org/10.48550/arXiv.2604.15963" target="_blank">arXiv:2604.15963</a>.
|
|
804
|
+
<details><summary>BibTeX</summary>
|
|
805
|
+
|
|
806
|
+
|
|
807
|
+
```bibtex
|
|
808
|
+
@article{10.1145/3803437.3806402,
|
|
809
|
+
author = {Sihler, Florian and Gerstl, Oliver and Pfrenger, Lars and Schubert, Julian and Tichy, Matthias},
|
|
810
|
+
title = {Supporting the Comprehension of Data Analysis Scripts},
|
|
811
|
+
year = {2026},
|
|
812
|
+
doi = {10.1145/3803437.3806402}
|
|
813
|
+
}
|
|
814
|
+
```
|
|
815
|
+
|
|
816
|
+
|
|
817
|
+
</details>
|
|
818
|
+
|
|
802
819
|
* [Statically Analyzing the Dataflow of R Programs (OOPSLA '25)](https://doi.org/10.1145/3763087)
|
|
803
|
-
Please cite this paper if you are using flowR in your research
|
|
820
|
+
**Please cite this paper if you are using flowR in your research.**
|
|
804
821
|
<details><summary>BibTeX</summary>
|
|
805
822
|
|
|
806
823
|
|
|
@@ -829,7 +846,7 @@ please check out the following publications (if you find that a paper is missing
|
|
|
829
846
|
</details>
|
|
830
847
|
|
|
831
848
|
* [flowR: A Static Program Slicer for R (ASE '24, Tool)](https://doi.org/10.1145/3691620.3695359)
|
|
832
|
-
This refers to the tool-demonstration of the <a href="https://marketplace.visualstudio.com/items?itemName=code-inspect.vscode-flowr">VS Code Extension</a>.
|
|
849
|
+
This refers to the tool-demonstration of the <a href="https://marketplace.visualstudio.com/items?itemName=code-inspect.vscode-flowr" target="_blank">VS Code Extension</a>.
|
|
833
850
|
<details><summary>BibTeX</summary>
|
|
834
851
|
|
|
835
852
|
|
|
@@ -1,37 +1,31 @@
|
|
|
1
|
-
import type
|
|
2
|
-
import {
|
|
3
|
-
import type { SemanticCfgGuidedVisitorConfiguration } from '../control-flow/semantic-cfg-guided-visitor';
|
|
4
|
-
import { SemanticCfgGuidedVisitor } from '../control-flow/semantic-cfg-guided-visitor';
|
|
1
|
+
import { type CfgExpressionVertex, type CfgStatementVertex, CfgVertex, type ControlFlowInformation } from '../control-flow/control-flow-graph';
|
|
2
|
+
import { SemanticCfgGuidedVisitor, type SemanticCfgGuidedVisitorConfiguration } from '../control-flow/semantic-cfg-guided-visitor';
|
|
5
3
|
import { BuiltInProcName } from '../dataflow/environments/built-in-proc-name';
|
|
6
4
|
import type { DataflowGraph } from '../dataflow/graph/graph';
|
|
7
5
|
import { type DataflowGraphVertexFunctionCall, type DataflowGraphVertexVariableDefinition } from '../dataflow/graph/vertex';
|
|
8
|
-
import type
|
|
6
|
+
import { type NoInfo, RNode } from '../r-bridge/lang-4.x/ast/model/model';
|
|
9
7
|
import type { NormalizedAst, ParentInformation } from '../r-bridge/lang-4.x/ast/model/processing/decorate';
|
|
10
8
|
import type { NodeId } from '../r-bridge/lang-4.x/ast/model/processing/node-id';
|
|
11
9
|
import { type AnyAbstractDomain } from './domains/abstract-domain';
|
|
12
|
-
import type {
|
|
10
|
+
import type { AnyStateDomain, ValueDomain } from './domains/state-domain-like';
|
|
13
11
|
export type AbsintVisitorConfiguration = Omit<SemanticCfgGuidedVisitorConfiguration<NoInfo, ControlFlowInformation, NormalizedAst>, 'defaultVisitingOrder' | 'defaultVisitingType'>;
|
|
14
12
|
/**
|
|
15
13
|
* A control flow graph visitor to perform abstract interpretation.
|
|
16
14
|
*
|
|
17
15
|
* However, the visitor does not yet support inter-procedural abstract interpretation and abstract condition semantics.
|
|
18
16
|
*/
|
|
19
|
-
export declare abstract class AbstractInterpretationVisitor<
|
|
17
|
+
export declare abstract class AbstractInterpretationVisitor<StateDomain extends AnyStateDomain<AnyAbstractDomain>, Config extends AbsintVisitorConfiguration = AbsintVisitorConfiguration> extends SemanticCfgGuidedVisitor<NoInfo, ControlFlowInformation, NormalizedAst, DataflowGraph, Config & {
|
|
20
18
|
defaultVisitingOrder: 'forward';
|
|
21
19
|
defaultVisitingType: 'exit';
|
|
22
20
|
}> {
|
|
23
21
|
/**
|
|
24
22
|
* The abstract trace of the abstract interpretation visitor mapping node IDs to the abstract state at the respective node.
|
|
25
23
|
*/
|
|
26
|
-
|
|
24
|
+
protected readonly trace: Map<NodeId, StateDomain>;
|
|
27
25
|
/**
|
|
28
26
|
* The current abstract state domain at the currently processed AST node.
|
|
29
27
|
*/
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* Whether the current abstract state has been copied/cloned and is save to modify in place.
|
|
33
|
-
*/
|
|
34
|
-
private stateCopied;
|
|
28
|
+
protected currentState: StateDomain;
|
|
35
29
|
/**
|
|
36
30
|
* The current worklist stack of next vertex IDs to visit.
|
|
37
31
|
*/
|
|
@@ -40,10 +34,11 @@ export declare abstract class AbstractInterpretationVisitor<Domain extends AnyAb
|
|
|
40
34
|
* A set of nodes representing variable definitions that have already been visited but whose assignment has not yet been processed.
|
|
41
35
|
*/
|
|
42
36
|
private readonly unassigned;
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
37
|
+
/**
|
|
38
|
+
* A map mapping assignments of replacement calls to their replacement calls for replacement calls that have already been visited but whose assignment has not yet been processed.
|
|
39
|
+
*/
|
|
40
|
+
private readonly replacements;
|
|
41
|
+
constructor(config: Config, stateDomain: StateDomain);
|
|
47
42
|
/**
|
|
48
43
|
* Resolves the inferred abstract value of an AST node.
|
|
49
44
|
* This requires that the abstract interpretation visitor has been completed, or at least started.
|
|
@@ -51,28 +46,29 @@ export declare abstract class AbstractInterpretationVisitor<Domain extends AnyAb
|
|
|
51
46
|
* @param state - An optional state abstract domain used to resolve the inferred abstract value (defaults to the state at the requested node)
|
|
52
47
|
* @returns The inferred abstract value of the node, or `undefined` if no value was inferred for the node
|
|
53
48
|
*/
|
|
54
|
-
getAbstractValue(id: RNode<ParentInformation> | NodeId | undefined, state?:
|
|
49
|
+
getAbstractValue(id: RNode<ParentInformation> | NodeId | undefined, state?: StateDomain): ValueDomain<StateDomain> | undefined;
|
|
55
50
|
/**
|
|
56
51
|
* Gets the inferred abstract state at the location of a specific AST node.
|
|
57
52
|
* This requires that the abstract interpretation visitor has been completed, or at least started.
|
|
58
53
|
* @param id - The ID of the node to get the abstract state at
|
|
59
54
|
* @returns The abstract state at the node, or `undefined` if the node has no abstract state (i.e. the node has not been visited or is unreachable).
|
|
60
55
|
*/
|
|
61
|
-
getAbstractState(id: NodeId | undefined):
|
|
56
|
+
getAbstractState(id: NodeId | undefined): StateDomain | undefined;
|
|
62
57
|
/**
|
|
63
58
|
* Gets the inferred abstract state at the end of the program (exit nodes of the control flow graph).
|
|
64
59
|
* This requires that the abstract interpretation visitor has been completed, or at least started.
|
|
65
60
|
* @returns The inferred abstract state at the end of the program
|
|
66
61
|
*/
|
|
67
|
-
getEndState():
|
|
62
|
+
getEndState(): StateDomain;
|
|
68
63
|
/**
|
|
69
64
|
* Gets the inferred abstract trace mapping AST nodes to the inferred abstract state at the respective node.
|
|
70
65
|
* @returns The inferred abstract trace of the program
|
|
71
66
|
*/
|
|
72
|
-
getAbstractTrace(): ReadonlyMap<NodeId,
|
|
67
|
+
getAbstractTrace(): ReadonlyMap<NodeId, StateDomain>;
|
|
73
68
|
start(): void;
|
|
74
69
|
protected startVisitor(start: readonly NodeId[]): void;
|
|
75
70
|
protected visitNode(vertexId: NodeId): boolean;
|
|
71
|
+
protected visitUnknown(vertex: CfgStatementVertex | CfgExpressionVertex): void;
|
|
76
72
|
protected onDispatchFunctionCallOrigin(call: DataflowGraphVertexFunctionCall, origin: BuiltInProcName): void;
|
|
77
73
|
protected onVariableDefinition({ vertex }: {
|
|
78
74
|
vertex: DataflowGraphVertexVariableDefinition;
|
|
@@ -11,7 +11,6 @@ const r_function_call_1 = require("../r-bridge/lang-4.x/ast/model/nodes/r-functi
|
|
|
11
11
|
const type_1 = require("../r-bridge/lang-4.x/ast/model/type");
|
|
12
12
|
const assert_1 = require("../util/assert");
|
|
13
13
|
const abstract_domain_1 = require("./domains/abstract-domain");
|
|
14
|
-
const state_abstract_domain_1 = require("./domains/state-abstract-domain");
|
|
15
14
|
const unsupported_functions_1 = require("./unsupported-functions");
|
|
16
15
|
/**
|
|
17
16
|
* A control flow graph visitor to perform abstract interpretation.
|
|
@@ -26,11 +25,7 @@ class AbstractInterpretationVisitor extends semantic_cfg_guided_visitor_1.Semant
|
|
|
26
25
|
/**
|
|
27
26
|
* The current abstract state domain at the currently processed AST node.
|
|
28
27
|
*/
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Whether the current abstract state has been copied/cloned and is save to modify in place.
|
|
32
|
-
*/
|
|
33
|
-
stateCopied = false;
|
|
28
|
+
currentState;
|
|
34
29
|
/**
|
|
35
30
|
* The current worklist stack of next vertex IDs to visit.
|
|
36
31
|
*/
|
|
@@ -39,26 +34,13 @@ class AbstractInterpretationVisitor extends semantic_cfg_guided_visitor_1.Semant
|
|
|
39
34
|
* A set of nodes representing variable definitions that have already been visited but whose assignment has not yet been processed.
|
|
40
35
|
*/
|
|
41
36
|
unassigned = new Set();
|
|
42
|
-
|
|
37
|
+
/**
|
|
38
|
+
* A map mapping assignments of replacement calls to their replacement calls for replacement calls that have already been visited but whose assignment has not yet been processed.
|
|
39
|
+
*/
|
|
40
|
+
replacements = new Map();
|
|
41
|
+
constructor(config, stateDomain) {
|
|
43
42
|
super({ ...config, defaultVisitingOrder: 'forward', defaultVisitingType: 'exit' });
|
|
44
|
-
this.
|
|
45
|
-
}
|
|
46
|
-
get currentState() {
|
|
47
|
-
return this._currentState;
|
|
48
|
-
}
|
|
49
|
-
removeState(node) {
|
|
50
|
-
if (!this.stateCopied) {
|
|
51
|
-
this._currentState = this._currentState.create(this.currentState.value);
|
|
52
|
-
this.stateCopied = true;
|
|
53
|
-
}
|
|
54
|
-
this._currentState.remove(node);
|
|
55
|
-
}
|
|
56
|
-
updateState(node, value) {
|
|
57
|
-
if (!this.stateCopied) {
|
|
58
|
-
this._currentState = this._currentState.create(this.currentState.value);
|
|
59
|
-
this.stateCopied = true;
|
|
60
|
-
}
|
|
61
|
-
this._currentState.set(node, value);
|
|
43
|
+
this.currentState = stateDomain.top();
|
|
62
44
|
}
|
|
63
45
|
/**
|
|
64
46
|
* Resolves the inferred abstract value of an AST node.
|
|
@@ -70,7 +52,10 @@ class AbstractInterpretationVisitor extends semantic_cfg_guided_visitor_1.Semant
|
|
|
70
52
|
getAbstractValue(id, state) {
|
|
71
53
|
const node = (id === undefined || typeof id === 'object') ? id : this.getNormalizedAst(id);
|
|
72
54
|
state ??= node !== undefined ? this.getAbstractState(node.info.id) : undefined;
|
|
73
|
-
if (
|
|
55
|
+
if (state?.isBottom()) {
|
|
56
|
+
return this.currentState.domain.bottom();
|
|
57
|
+
}
|
|
58
|
+
else if (node === undefined) {
|
|
74
59
|
return;
|
|
75
60
|
}
|
|
76
61
|
else if (state?.has(node.info.id)) {
|
|
@@ -80,7 +65,8 @@ class AbstractInterpretationVisitor extends semantic_cfg_guided_visitor_1.Semant
|
|
|
80
65
|
const call = (0, vertex_1.isFunctionCallVertex)(vertex) ? vertex : undefined;
|
|
81
66
|
const origins = Array.isArray(call?.origin) ? call.origin : [];
|
|
82
67
|
if (node.type === type_1.RType.Symbol) {
|
|
83
|
-
const values = this.getVariableOrigins(node.info.id)
|
|
68
|
+
const values = this.getVariableOrigins(node.info.id)
|
|
69
|
+
.map(origin => (this.getAbstractState(origin)?.isBottom() ? this.currentState.domain.bottom() : state?.get(origin)));
|
|
84
70
|
if (values.length > 0 && values.every(assert_1.isNotUndefined)) {
|
|
85
71
|
return abstract_domain_1.AbstractDomain.joinAll(values);
|
|
86
72
|
}
|
|
@@ -130,7 +116,7 @@ class AbstractInterpretationVisitor extends semantic_cfg_guided_visitor_1.Semant
|
|
|
130
116
|
const exitPoints = this.config.controlFlow.exitPoints.map(id => this.getCfgVertex(id)).filter(assert_1.isNotUndefined);
|
|
131
117
|
const exitNodes = exitPoints.map(control_flow_graph_1.CfgVertex.getRootId).filter(assert_1.isNotUndefined);
|
|
132
118
|
const states = exitNodes.map(node => this.trace.get(node)).filter(assert_1.isNotUndefined);
|
|
133
|
-
return abstract_domain_1.AbstractDomain.joinAll(states, this.
|
|
119
|
+
return abstract_domain_1.AbstractDomain.joinAll(states, this.currentState.bottom());
|
|
134
120
|
}
|
|
135
121
|
/**
|
|
136
122
|
* Gets the inferred abstract trace mapping AST nodes to the inferred abstract state at the respective node.
|
|
@@ -165,40 +151,30 @@ class AbstractInterpretationVisitor extends semantic_cfg_guided_visitor_1.Semant
|
|
|
165
151
|
if (vertex === undefined || this.shouldSkipVertex(vertex)) {
|
|
166
152
|
return true;
|
|
167
153
|
}
|
|
154
|
+
// retrieve new abstract state by joining states of predecessor nodes
|
|
168
155
|
const predecessors = this.getPredecessorNodes(control_flow_graph_1.CfgVertex.getId(vertex));
|
|
169
156
|
const predecessorStates = predecessors.map(pred => this.trace.get(pred)).filter(assert_1.isNotUndefined);
|
|
170
|
-
|
|
171
|
-
if (predecessorStates.length <= 1) {
|
|
172
|
-
this._currentState = predecessorStates[0] ?? this._currentState.top();
|
|
173
|
-
}
|
|
174
|
-
else {
|
|
175
|
-
this._currentState = abstract_domain_1.AbstractDomain.joinAll(predecessorStates);
|
|
176
|
-
this.stateCopied = true;
|
|
177
|
-
}
|
|
157
|
+
this.currentState = abstract_domain_1.AbstractDomain.joinAll(predecessorStates, this.currentState.top());
|
|
178
158
|
const nodeId = control_flow_graph_1.CfgVertex.getRootId(vertex);
|
|
179
159
|
// differentiate between widening points and other vertices
|
|
180
160
|
if (this.isWideningPoint(nodeId)) {
|
|
181
161
|
const oldState = this.trace.get(nodeId);
|
|
182
162
|
if (oldState !== undefined && this.shouldWiden(vertex)) {
|
|
183
|
-
this.
|
|
184
|
-
this.stateCopied = true;
|
|
163
|
+
this.currentState = oldState.widen(this.currentState);
|
|
185
164
|
}
|
|
186
|
-
this.trace.set(nodeId, this.
|
|
187
|
-
this.stateCopied = false;
|
|
165
|
+
this.trace.set(nodeId, this.currentState);
|
|
188
166
|
const visitedCount = this.visited.get(nodeId) ?? 0;
|
|
189
167
|
this.visited.set(nodeId, visitedCount + 1);
|
|
190
168
|
// continue visiting after widening point if visited for the first time or the state changed
|
|
191
|
-
return visitedCount === 0 || !oldState?.equals(this.
|
|
169
|
+
return visitedCount === 0 || !oldState?.equals(this.currentState);
|
|
192
170
|
}
|
|
193
171
|
else {
|
|
194
172
|
this.onVisitNode(vertexId);
|
|
195
173
|
// discard the inferred abstract state when encountering unsupported function calls
|
|
196
174
|
if (this.isUnsupportedFunctionCall(nodeId)) {
|
|
197
|
-
this.
|
|
198
|
-
this.stateCopied = true;
|
|
175
|
+
this.currentState = this.currentState.top();
|
|
199
176
|
}
|
|
200
|
-
this.trace.set(nodeId, this.
|
|
201
|
-
this.stateCopied = false;
|
|
177
|
+
this.trace.set(nodeId, this.currentState);
|
|
202
178
|
const predecessorVisits = predecessors.map(pred => this.visited.get(pred) ?? 0);
|
|
203
179
|
const visitedCount = this.visited.get(nodeId) ?? 0;
|
|
204
180
|
this.visited.set(nodeId, visitedCount + 1);
|
|
@@ -206,7 +182,31 @@ class AbstractInterpretationVisitor extends semantic_cfg_guided_visitor_1.Semant
|
|
|
206
182
|
return predecessors.length <= 1 || this.stack.length === 0 || predecessorVisits.every(visits => visits === predecessorVisits[0]);
|
|
207
183
|
}
|
|
208
184
|
}
|
|
185
|
+
visitUnknown(vertex) {
|
|
186
|
+
const nodeId = control_flow_graph_1.CfgVertex.getRootId(vertex);
|
|
187
|
+
const replacements = this.replacements.get(nodeId);
|
|
188
|
+
if (replacements !== undefined) {
|
|
189
|
+
this.replacements.delete(nodeId);
|
|
190
|
+
for (const replacement of replacements) {
|
|
191
|
+
const call = this.getDataflowGraph(replacement);
|
|
192
|
+
if ((0, vertex_1.isFunctionCallVertex)(call)) {
|
|
193
|
+
this.onReplacementCall({ call, ...this.getSourceAndTarget(call) });
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
209
198
|
onDispatchFunctionCallOrigin(call, origin) {
|
|
199
|
+
if (origin === built_in_proc_name_1.BuiltInProcName.Replacement) {
|
|
200
|
+
const node = this.getNormalizedAst(call.id);
|
|
201
|
+
const assignment = model_1.RNode.iterateParents(node, this.config.normalizedAst.idMap)
|
|
202
|
+
.find(parent => this.getDataflowGraph(parent.info.id) === undefined);
|
|
203
|
+
if (node !== undefined && assignment !== undefined) {
|
|
204
|
+
const replacements = this.replacements.get(assignment.info.id) ?? [];
|
|
205
|
+
replacements.push(node.info.id);
|
|
206
|
+
this.replacements.set(assignment.info.id, replacements);
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
210
|
super.onDispatchFunctionCallOrigin(call, origin);
|
|
211
211
|
switch (origin) {
|
|
212
212
|
case built_in_proc_name_1.BuiltInProcName.ExpressionList:
|
|
@@ -240,9 +240,8 @@ class AbstractInterpretationVisitor extends semantic_cfg_guided_visitor_1.Semant
|
|
|
240
240
|
const value = this.getAbstractValue(source);
|
|
241
241
|
this.unassigned.delete(target);
|
|
242
242
|
if (value !== undefined) {
|
|
243
|
-
this.
|
|
244
|
-
this.trace.set(target, this.
|
|
245
|
-
this.stateCopied = false;
|
|
243
|
+
this.currentState.set(target, value);
|
|
244
|
+
this.trace.set(target, this.currentState);
|
|
246
245
|
}
|
|
247
246
|
}
|
|
248
247
|
onReplacementCall({ target }) {
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import type { AbstractDomainValue } from '../domains/abstract-domain';
|
|
2
1
|
import { PosIntervalDomain } from '../domains/positive-interval-domain';
|
|
3
2
|
import { ProductDomain } from '../domains/product-domain';
|
|
4
3
|
import { SetRangeDomain } from '../domains/set-range-domain';
|
|
@@ -8,8 +7,6 @@ export type AbstractDataFrameShape = {
|
|
|
8
7
|
cols: PosIntervalDomain;
|
|
9
8
|
rows: PosIntervalDomain;
|
|
10
9
|
};
|
|
11
|
-
/** The type of abstract values of a sub abstract domain (shape property) of the data frame shape product domain */
|
|
12
|
-
export type DataFrameShapeProperty<Property extends keyof AbstractDataFrameShape> = AbstractDomainValue<AbstractDataFrameShape[Property]>;
|
|
13
10
|
/**
|
|
14
11
|
* The data frame abstract domain as product domain of a column names domain, column count domain, and row count domain.
|
|
15
12
|
*/
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { DataflowGraphVertexFunctionCall } from '../../dataflow/graph/vertex';
|
|
2
2
|
import type { NodeId } from '../../r-bridge/lang-4.x/ast/model/processing/node-id';
|
|
3
3
|
import { AbstractInterpretationVisitor, type AbsintVisitorConfiguration } from '../absint-visitor';
|
|
4
|
+
import { StateAbstractDomain } from '../domains/state-abstract-domain';
|
|
4
5
|
import { DataFrameDomain } from './dataframe-domain';
|
|
5
6
|
import { ConstraintType, type DataFrameOperationArgs, type DataFrameOperationName, type DataFrameOperationOptions } from './semantics';
|
|
6
7
|
interface Operation<Name extends DataFrameOperationName> {
|
|
@@ -35,7 +36,7 @@ interface DataFrameShapeInferenceConfiguration extends AbsintVisitorConfiguratio
|
|
|
35
36
|
/**
|
|
36
37
|
* The control flow graph visitor to infer the shape of data frames using abstract interpretation
|
|
37
38
|
*/
|
|
38
|
-
export declare class DataFrameShapeInferenceVisitor extends AbstractInterpretationVisitor<DataFrameDomain
|
|
39
|
+
export declare class DataFrameShapeInferenceVisitor extends AbstractInterpretationVisitor<StateAbstractDomain<DataFrameDomain>, DataFrameShapeInferenceConfiguration> {
|
|
39
40
|
/**
|
|
40
41
|
* The abstract data frame operations the function call nodes are mapped to.
|
|
41
42
|
*/
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.DataFrameShapeInferenceVisitor = void 0;
|
|
4
4
|
const absint_visitor_1 = require("../absint-visitor");
|
|
5
|
+
const state_abstract_domain_1 = require("../domains/state-abstract-domain");
|
|
5
6
|
const dataframe_domain_1 = require("./dataframe-domain");
|
|
6
7
|
const access_mapper_1 = require("./mappers/access-mapper");
|
|
7
8
|
const function_mapper_1 = require("./mappers/function-mapper");
|
|
@@ -16,7 +17,7 @@ class DataFrameShapeInferenceVisitor extends absint_visitor_1.AbstractInterpreta
|
|
|
16
17
|
*/
|
|
17
18
|
operations;
|
|
18
19
|
constructor({ trackOperations = true, ...config }) {
|
|
19
|
-
super(config, dataframe_domain_1.DataFrameDomain.top());
|
|
20
|
+
super(config, state_abstract_domain_1.StateAbstractDomain.top(dataframe_domain_1.DataFrameDomain.top()));
|
|
20
21
|
if (trackOperations) {
|
|
21
22
|
this.operations = new Map();
|
|
22
23
|
}
|
|
@@ -73,13 +74,13 @@ class DataFrameShapeInferenceVisitor extends absint_visitor_1.AbstractInterpreta
|
|
|
73
74
|
value = (0, semantics_1.applyDataFrameSemantics)(operation, operandValue ?? dataframe_domain_1.DataFrameDomain.top(maxColNames), args, options);
|
|
74
75
|
const constraintType = type ?? (0, semantics_1.getConstraintType)(operation);
|
|
75
76
|
if (operand !== undefined && constraintType === semantics_1.ConstraintType.OperandModification) {
|
|
76
|
-
this.
|
|
77
|
+
this.currentState.set(operand, value);
|
|
77
78
|
for (const origin of this.getVariableOrigins(operand)) {
|
|
78
|
-
this.
|
|
79
|
+
this.currentState.set(origin, value);
|
|
79
80
|
}
|
|
80
81
|
}
|
|
81
82
|
else if (constraintType === semantics_1.ConstraintType.ResultPostcondition) {
|
|
82
|
-
this.
|
|
83
|
+
this.currentState.set(node.info.id, value);
|
|
83
84
|
}
|
|
84
85
|
}
|
|
85
86
|
}
|
|
@@ -63,36 +63,37 @@ export declare abstract class AbstractDomain<Concrete, Abstract, Top, Bot, Value
|
|
|
63
63
|
* The provided array of abstract values must not be empty or a default value must be provided!
|
|
64
64
|
*/
|
|
65
65
|
static meetAll<Domain extends AnyAbstractDomain>(values: Domain[], defaultValue?: Domain): Domain;
|
|
66
|
+
/**
|
|
67
|
+
* Converts an element of an abstract domain into a string.
|
|
68
|
+
*/
|
|
69
|
+
static toString(this: void, value: AnyAbstractDomain | unknown): string;
|
|
66
70
|
}
|
|
67
71
|
/**
|
|
68
72
|
* A type representing any abstract domain without additional information.
|
|
69
73
|
*/
|
|
70
74
|
export type AnyAbstractDomain = AbstractDomain<unknown, unknown, unknown, unknown>;
|
|
71
|
-
/**
|
|
72
|
-
* The type of the concrete domain of an abstract domain.
|
|
73
|
-
* @template Domain - The abstract domain to get the concrete domain type for
|
|
74
|
-
*/
|
|
75
|
-
export type ConcreteDomain<Domain extends AnyAbstractDomain> = Domain extends AbstractDomain<infer Concrete, unknown, unknown, unknown> ? Concrete : never;
|
|
76
75
|
/**
|
|
77
76
|
* The type of the abstract values of an abstract domain (including the Top and Bottom element).
|
|
78
77
|
* @template Domain - The abstract domain to get the abstract value type for
|
|
79
78
|
*/
|
|
80
|
-
export type
|
|
79
|
+
export type AbstractValue<Domain extends AnyAbstractDomain> = Domain extends AbstractDomain<unknown, infer Value, infer Top, infer Bot> ? Value | Top | Bot : never;
|
|
81
80
|
/**
|
|
82
|
-
* The type of the
|
|
83
|
-
* @template Domain - The abstract domain to get the
|
|
81
|
+
* The type of the concrete domain of an abstract domain.
|
|
82
|
+
* @template Domain - The abstract domain to get the concrete domain type for
|
|
84
83
|
*/
|
|
85
|
-
export type
|
|
84
|
+
export type ConcreteDomain<Domain extends AnyAbstractDomain> = Domain extends AbstractDomain<infer Concrete, unknown, unknown, unknown> ? Concrete : never;
|
|
86
85
|
/**
|
|
87
|
-
* The type of
|
|
88
|
-
* @template Domain - The abstract domain
|
|
86
|
+
* The type of an abstract domain holding an abstract value of the domain.
|
|
87
|
+
* @template Domain - The abstract domain abstract domain value type for
|
|
89
88
|
*/
|
|
90
|
-
export type
|
|
89
|
+
export type AbstractDomainValue<Domain extends AnyAbstractDomain> = Domain extends AbstractDomain<infer Concrete, infer Value, infer Top, infer Bot> ? Domain & AbstractDomain<Concrete, Value, Top, Bot, Value> : never;
|
|
91
90
|
/**
|
|
92
|
-
*
|
|
91
|
+
* The type an abstract domain holding the Top element (greatest element) of the domain.
|
|
92
|
+
* @template Domain - The abstract domain to get the abstract domain top for
|
|
93
93
|
*/
|
|
94
|
-
export
|
|
94
|
+
export type AbstractDomainTop<Domain extends AnyAbstractDomain> = Domain extends AbstractDomain<infer Concrete, infer Value, infer Top, infer Bot> ? Domain & AbstractDomain<Concrete, Value, Top, Bot, Top> : never;
|
|
95
95
|
/**
|
|
96
|
-
*
|
|
96
|
+
* The type an abstract domain holding the Bottom element (least element) of the domain.
|
|
97
|
+
* @template Domain - The abstract domain to get the abstract domain bottom for
|
|
97
98
|
*/
|
|
98
|
-
export
|
|
99
|
+
export type AbstractDomainBottom<Domain extends AnyAbstractDomain> = Domain extends AbstractDomain<infer Concrete, infer Value, infer Top, infer Bot> ? Domain & AbstractDomain<Concrete, Value, Top, Bot, Bot> : never;
|