@eagleoutice/flowr 2.9.14 → 2.10.2
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 +52 -29
- package/abstract-interpretation/absint-visitor.d.ts +13 -8
- package/abstract-interpretation/absint-visitor.js +35 -26
- package/abstract-interpretation/data-frame/dataframe-domain.d.ts +1 -2
- package/abstract-interpretation/data-frame/dataframe-domain.js +14 -15
- package/abstract-interpretation/data-frame/mappers/access-mapper.js +2 -15
- package/abstract-interpretation/data-frame/mappers/arguments.d.ts +11 -17
- package/abstract-interpretation/data-frame/mappers/arguments.js +18 -18
- package/abstract-interpretation/data-frame/mappers/function-mapper.d.ts +41 -15
- package/abstract-interpretation/data-frame/mappers/function-mapper.js +74 -48
- package/abstract-interpretation/data-frame/mappers/replacement-mapper.js +2 -1
- package/abstract-interpretation/data-frame/semantics.d.ts +1 -1
- package/abstract-interpretation/data-frame/semantics.js +31 -35
- package/abstract-interpretation/data-frame/shape-inference.js +1 -1
- package/abstract-interpretation/domains/interval-domain.d.ts +1 -0
- package/abstract-interpretation/domains/interval-domain.js +3 -0
- package/abstract-interpretation/domains/product-domain.d.ts +9 -0
- package/abstract-interpretation/domains/product-domain.js +26 -6
- package/abstract-interpretation/domains/state-abstract-domain.d.ts +36 -22
- package/abstract-interpretation/domains/state-abstract-domain.js +169 -62
- package/abstract-interpretation/unsupported-functions.d.ts +10 -0
- package/abstract-interpretation/unsupported-functions.js +45 -0
- package/benchmark/slicer.js +10 -13
- package/benchmark/stats/stats.d.ts +2 -2
- package/cli/flowr.js +1 -1
- package/cli/repl/parser/slice-query-parser.d.ts +2 -2
- package/config.d.ts +4 -0
- package/config.js +5 -3
- package/control-flow/control-flow-graph.js +13 -9
- package/control-flow/semantic-cfg-guided-visitor.d.ts +6 -0
- package/control-flow/semantic-cfg-guided-visitor.js +6 -0
- package/dataflow/environments/built-in-proc-name.d.ts +6 -0
- package/dataflow/environments/built-in-proc-name.js +6 -0
- package/dataflow/environments/built-in.d.ts +7 -5
- package/dataflow/environments/built-in.js +2 -0
- package/dataflow/environments/default-builtin-config.d.ts +442 -6
- package/dataflow/environments/default-builtin-config.js +158 -3
- package/dataflow/environments/identifier.d.ts +4 -0
- package/dataflow/environments/identifier.js +17 -0
- package/dataflow/environments/overwrite.js +2 -5
- package/dataflow/graph/call-graph.d.ts +4 -7
- package/dataflow/graph/call-graph.js +0 -22
- package/dataflow/graph/df-helper.d.ts +23 -12
- package/dataflow/graph/df-helper.js +44 -7
- package/dataflow/graph/graph-helper.d.ts +9 -4
- package/dataflow/graph/graph-helper.js +26 -3
- package/dataflow/graph/graph.d.ts +23 -2
- package/dataflow/graph/graph.js +38 -4
- package/dataflow/graph/vertex.d.ts +2 -0
- package/dataflow/instrument/instrument-dataflow-count.d.ts +10 -0
- package/dataflow/instrument/instrument-dataflow-count.js +10 -0
- package/dataflow/internal/process/functions/call/argument/unpack-argument.d.ts +4 -4
- package/dataflow/internal/process/functions/call/built-in/built-in-access.d.ts +3 -3
- package/dataflow/internal/process/functions/call/built-in/built-in-apply.d.ts +2 -2
- 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.d.ts +3 -3
- package/dataflow/internal/process/functions/call/built-in/built-in-assignment.js +1 -1
- package/dataflow/internal/process/functions/call/built-in/built-in-eval.d.ts +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-expression-list.d.ts +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-for-loop.d.ts +2 -2
- 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.d.ts +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-function-definition.js +8 -19
- package/dataflow/internal/process/functions/call/built-in/built-in-get.d.ts +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-if-then-else.d.ts +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-library.d.ts +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-list.d.ts +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-local.d.ts +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-pipe.d.ts +23 -3
- package/dataflow/internal/process/functions/call/built-in/built-in-pipe.js +80 -12
- package/dataflow/internal/process/functions/call/built-in/built-in-purrr-formula.d.ts +41 -0
- package/dataflow/internal/process/functions/call/built-in/built-in-purrr-formula.js +179 -0
- package/dataflow/internal/process/functions/call/built-in/built-in-quote.d.ts +7 -4
- package/dataflow/internal/process/functions/call/built-in/built-in-quote.js +62 -1
- package/dataflow/internal/process/functions/call/built-in/built-in-recall.d.ts +7 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-recall.js +15 -1
- package/dataflow/internal/process/functions/call/built-in/built-in-register-hook.d.ts +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-repeat-loop.d.ts +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-replacement.d.ts +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-rm.d.ts +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-s-seven-dispatch.d.ts +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-s-seven-new-generic.d.ts +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-s-three-dispatch.d.ts +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-source.d.ts +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-special-bin-op.d.ts +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-stop-if-not.d.ts +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-try-catch.d.ts +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-vector.d.ts +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-while-loop.d.ts +2 -2
- package/dataflow/internal/process/functions/call/common.d.ts +2 -2
- package/dataflow/internal/process/functions/call/common.js +6 -4
- package/dataflow/internal/process/functions/call/known-call-handling.d.ts +2 -2
- package/dataflow/internal/process/functions/call/named-call-handling.d.ts +2 -2
- package/dataflow/internal/process/functions/process-parameter.js +1 -1
- package/documentation/doc-readme.js +2 -1
- package/documentation/wiki-absint.js +6 -5
- package/documentation/wiki-analyzer.js +0 -2
- package/documentation/wiki-linter.js +6 -0
- package/documentation/wiki-normalized-ast.js +7 -7
- package/linter/linter-rules.d.ts +49 -1
- package/linter/linter-rules.js +5 -1
- package/linter/rules/dataframe-access-validation.d.ts +1 -1
- package/linter/rules/dataframe-access-validation.js +3 -4
- package/linter/rules/problematic-eval.d.ts +44 -0
- package/linter/rules/problematic-eval.js +83 -0
- package/linter/rules/roxygen-arguments.d.ts +35 -0
- package/linter/rules/roxygen-arguments.js +100 -0
- package/package.json +8 -9
- package/project/context/flowr-analyzer-context.d.ts +1 -8
- package/project/context/flowr-analyzer-context.js +1 -7
- package/project/context/flowr-analyzer-environment-context.d.ts +5 -0
- package/project/context/flowr-analyzer-environment-context.js +6 -0
- package/project/context/flowr-analyzer-files-context.d.ts +6 -0
- package/project/context/flowr-analyzer-files-context.js +4 -2
- package/project/flowr-analyzer-builder.js +1 -4
- package/queries/catalog/call-context-query/call-context-query-executor.d.ts +1 -1
- package/queries/catalog/call-context-query/call-context-query-executor.js +10 -5
- package/queries/catalog/call-context-query/call-context-query-format.d.ts +1 -1
- package/queries/catalog/dependencies-query/function-info/library-functions.js +2 -0
- 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/df-shape-query/df-shape-query-format.js +7 -2
- 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/files-query/files-query-executor.js +0 -1
- 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 +92 -0
- package/queries/catalog/input-sources-query/simple-input-classifier.js +310 -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/data/data.d.ts +2 -2
- package/r-bridge/data/data.js +2 -2
- 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 +29 -6
- package/r-bridge/lang-4.x/ast/model/nodes/r-argument.js +16 -2
- 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 +19 -4
- 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 +25 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-pipe.js +15 -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/r-bridge/lang-4.x/ast/model/versions.d.ts +2 -0
- package/r-bridge/lang-4.x/ast/model/versions.js +3 -1
- package/r-bridge/roxygen2/documentation-provider.js +15 -6
- package/r-bridge/roxygen2/roxygen-ast.d.ts +3 -1
- package/search/flowr-search-builder.js +3 -2
- 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/ast.js +2 -1
- package/util/mermaid/dfg.js +2 -1
- package/util/record.d.ts +23 -0
- package/util/record.js +33 -0
- package/util/version.js +1 -1
- package/abstract-interpretation/domains/mapped-abstract-domain.d.ts +0 -41
- package/abstract-interpretation/domains/mapped-abstract-domain.js +0 -213
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.1, 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,13 +53,17 @@ 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
|
|
65
|
+
╰ Roxygen Arguments (roxygen-arguments):
|
|
66
|
+
╰ Metadata: searchTimeMs: 0, processTimeMs: 0
|
|
63
67
|
All queries together required ≈2 ms (1ms accuracy, total 2 ms)
|
|
64
68
|
```
|
|
65
69
|
|
|
@@ -82,15 +86,15 @@ It offers a wide variety of features, for example:
|
|
|
82
86
|
|
|
83
87
|
_Results (prettified and summarized):_
|
|
84
88
|
|
|
85
|
-
Query: **linter** (
|
|
89
|
+
Query: **linter** (3 ms)\
|
|
86
90
|
╰ **Deprecated Functions** (deprecated-functions):\
|
|
87
|
-
╰ _Metadata_: <code>totalCalls: 0, totalFunctionDefinitions: 0, searchTimeMs:
|
|
91
|
+
╰ _Metadata_: <code>totalCalls: 0, totalFunctionDefinitions: 0, searchTimeMs: 1, processTimeMs: 0</code>\
|
|
88
92
|
╰ **File Path Validity** (file-path-validity):\
|
|
89
93
|
╰ certain:\
|
|
90
94
|
╰ Path `/root/x.txt` at 1.1-23\
|
|
91
|
-
╰ _Metadata_: <code>totalReads: 1, totalUnknown: 0, totalWritesBeforeAlways: 0, totalValid: 0, searchTimeMs:
|
|
95
|
+
╰ _Metadata_: <code>totalReads: 1, totalUnknown: 0, totalWritesBeforeAlways: 0, totalValid: 0, searchTimeMs: 0, processTimeMs: 0</code>\
|
|
92
96
|
╰ **Seeded Randomness** (seeded-randomness):\
|
|
93
|
-
╰ _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: 1, processTimeMs: 0</code>\
|
|
94
98
|
╰ **Absolute Paths** (absolute-file-paths):\
|
|
95
99
|
╰ certain:\
|
|
96
100
|
╰ Path `/root/x.txt` at 1.1-23\
|
|
@@ -107,13 +111,17 @@ It offers a wide variety of features, for example:
|
|
|
107
111
|
╰ _Metadata_: <code>consideredNodes: 5, searchTimeMs: 0, processTimeMs: 0</code>\
|
|
108
112
|
╰ **Useless Loops** (useless-loop):\
|
|
109
113
|
╰ _Metadata_: <code>numOfUselessLoops: 0, searchTimeMs: 0, processTimeMs: 0</code>\
|
|
114
|
+
╰ **Problematic eval** (problematic-eval):\
|
|
115
|
+
╰ _Metadata_: <code>searchTimeMs: 0, processTimeMs: 0</code>\
|
|
110
116
|
╰ **Stop without call.=False argument** (stop-call):\
|
|
111
117
|
╰ _Metadata_: <code>consideredNodes: 0, searchTimeMs: 0, processTimeMs: 0</code>\
|
|
112
|
-
|
|
118
|
+
╰ **Roxygen Arguments** (roxygen-arguments):\
|
|
119
|
+
╰ _Metadata_: <code>searchTimeMs: 0, processTimeMs: 0</code>\
|
|
120
|
+
_All queries together required ≈3 ms (1ms accuracy, total 3 ms)_
|
|
113
121
|
|
|
114
122
|
<details> <summary style="color:gray">Show Detailed Results as Json</summary>
|
|
115
123
|
|
|
116
|
-
The analysis required
|
|
124
|
+
The analysis required _3.4 ms_ (including parsing and normalization and the query) within the generation environment.
|
|
117
125
|
|
|
118
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.
|
|
119
127
|
Please consult the [Interface](https://github.com/flowr-analysis/flowr/wiki/Interface) wiki page for more information on how to get those.
|
|
@@ -130,7 +138,7 @@ It offers a wide variety of features, for example:
|
|
|
130
138
|
".meta": {
|
|
131
139
|
"totalCalls": 0,
|
|
132
140
|
"totalFunctionDefinitions": 0,
|
|
133
|
-
"searchTimeMs":
|
|
141
|
+
"searchTimeMs": 1,
|
|
134
142
|
"processTimeMs": 0
|
|
135
143
|
}
|
|
136
144
|
},
|
|
@@ -153,7 +161,7 @@ It offers a wide variety of features, for example:
|
|
|
153
161
|
"totalUnknown": 0,
|
|
154
162
|
"totalWritesBeforeAlways": 0,
|
|
155
163
|
"totalValid": 0,
|
|
156
|
-
"searchTimeMs":
|
|
164
|
+
"searchTimeMs": 0,
|
|
157
165
|
"processTimeMs": 0
|
|
158
166
|
}
|
|
159
167
|
},
|
|
@@ -165,7 +173,7 @@ It offers a wide variety of features, for example:
|
|
|
165
173
|
"callsWithAssignmentProducers": 0,
|
|
166
174
|
"callsWithNonConstantProducers": 0,
|
|
167
175
|
"callsWithOtherBranchProducers": 0,
|
|
168
|
-
"searchTimeMs":
|
|
176
|
+
"searchTimeMs": 1,
|
|
169
177
|
"processTimeMs": 0
|
|
170
178
|
}
|
|
171
179
|
},
|
|
@@ -241,6 +249,13 @@ It offers a wide variety of features, for example:
|
|
|
241
249
|
"processTimeMs": 0
|
|
242
250
|
}
|
|
243
251
|
},
|
|
252
|
+
"problematic-eval": {
|
|
253
|
+
"results": [],
|
|
254
|
+
".meta": {
|
|
255
|
+
"searchTimeMs": 0,
|
|
256
|
+
"processTimeMs": 0
|
|
257
|
+
}
|
|
258
|
+
},
|
|
244
259
|
"stop-call": {
|
|
245
260
|
"results": [],
|
|
246
261
|
".meta": {
|
|
@@ -248,14 +263,21 @@ It offers a wide variety of features, for example:
|
|
|
248
263
|
"searchTimeMs": 0,
|
|
249
264
|
"processTimeMs": 0
|
|
250
265
|
}
|
|
266
|
+
},
|
|
267
|
+
"roxygen-arguments": {
|
|
268
|
+
"results": [],
|
|
269
|
+
".meta": {
|
|
270
|
+
"searchTimeMs": 0,
|
|
271
|
+
"processTimeMs": 0
|
|
272
|
+
}
|
|
251
273
|
}
|
|
252
274
|
},
|
|
253
275
|
".meta": {
|
|
254
|
-
"timing":
|
|
276
|
+
"timing": 3
|
|
255
277
|
}
|
|
256
278
|
},
|
|
257
279
|
".meta": {
|
|
258
|
-
"timing":
|
|
280
|
+
"timing": 3
|
|
259
281
|
}
|
|
260
282
|
}
|
|
261
283
|
```
|
|
@@ -320,7 +342,7 @@ It offers a wide variety of features, for example:
|
|
|
320
342
|
|
|
321
343
|
```shell
|
|
322
344
|
$ docker run -it --rm eagleoutice/flowr # or npm run flowr
|
|
323
|
-
flowR repl using flowR v2.
|
|
345
|
+
flowR repl using flowR v2.10.1, R grammar v14 (tree-sitter engine)
|
|
324
346
|
R> :query @static-slice (11@sum) file://test/testfiles/example.R
|
|
325
347
|
```
|
|
326
348
|
|
|
@@ -334,7 +356,7 @@ It offers a wide variety of features, for example:
|
|
|
334
356
|
N <- 10
|
|
335
357
|
for(i in 1:(N-1)) sum <- sum + i + w
|
|
336
358
|
sum
|
|
337
|
-
All queries together required ≈
|
|
359
|
+
All queries together required ≈2 ms (1ms accuracy, total 2 ms)
|
|
338
360
|
```
|
|
339
361
|
|
|
340
362
|
|
|
@@ -368,7 +390,7 @@ It offers a wide variety of features, for example:
|
|
|
368
390
|
|
|
369
391
|
|
|
370
392
|
* 🚀 **fast call-graph, data-, and control-flow graphs**\
|
|
371
|
-
Within just [<i><span title="This measurement is automatically fetched from the latest benchmark!">101
|
|
393
|
+
Within just [<i><span title="This measurement is automatically fetched from the latest benchmark!">101 ms</span></i> (as of Mar 21, 2026)](https://flowr-analysis.github.io/flowr/wiki/stats/benchmark),
|
|
372
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,
|
|
373
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).
|
|
374
396
|
|
|
@@ -404,7 +426,7 @@ It offers a wide variety of features, for example:
|
|
|
404
426
|
|
|
405
427
|
```shell
|
|
406
428
|
$ docker run -it --rm eagleoutice/flowr # or npm run flowr
|
|
407
|
-
flowR repl using flowR v2.
|
|
429
|
+
flowR repl using flowR v2.10.1, R grammar v14 (tree-sitter engine)
|
|
408
430
|
R> :dataflow* test/testfiles/example.R
|
|
409
431
|
```
|
|
410
432
|
|
|
@@ -430,7 +452,7 @@ It offers a wide variety of features, for example:
|
|
|
430
452
|
*1.8*`"}}
|
|
431
453
|
%% No edges found for 1
|
|
432
454
|
0["`#91;RSymbol#93; sum
|
|
433
|
-
(0)
|
|
455
|
+
(0, sources: [1])
|
|
434
456
|
*1.1-3*`"]
|
|
435
457
|
2[["`#91;RBinaryOp#93; #60;#45;
|
|
436
458
|
(2)
|
|
@@ -444,7 +466,7 @@ It offers a wide variety of features, for example:
|
|
|
444
466
|
*2.12*`"}}
|
|
445
467
|
%% No edges found for 4
|
|
446
468
|
3["`#91;RSymbol#93; product
|
|
447
|
-
(3)
|
|
469
|
+
(3, sources: [4])
|
|
448
470
|
*2.1-7*`"]
|
|
449
471
|
5[["`#91;RBinaryOp#93; #60;#45;
|
|
450
472
|
(5)
|
|
@@ -455,7 +477,7 @@ It offers a wide variety of features, for example:
|
|
|
455
477
|
*3.6*`"}}
|
|
456
478
|
%% No edges found for 7
|
|
457
479
|
6["`#91;RSymbol#93; w
|
|
458
|
-
(6)
|
|
480
|
+
(6, sources: [7])
|
|
459
481
|
*3.1*`"]
|
|
460
482
|
8[["`#91;RBinaryOp#93; #60;#45;
|
|
461
483
|
(8)
|
|
@@ -466,14 +488,14 @@ It offers a wide variety of features, for example:
|
|
|
466
488
|
*4.6-7*`"}}
|
|
467
489
|
%% No edges found for 10
|
|
468
490
|
9["`#91;RSymbol#93; N
|
|
469
|
-
(9)
|
|
491
|
+
(9, sources: [10])
|
|
470
492
|
*4.1*`"]
|
|
471
493
|
11[["`#91;RBinaryOp#93; #60;#45;
|
|
472
494
|
(11)
|
|
473
495
|
*4.1-7*
|
|
474
496
|
(9, 10)`"]]
|
|
475
497
|
12["`#91;RSymbol#93; i
|
|
476
|
-
(12)
|
|
498
|
+
(12, sources: [20])
|
|
477
499
|
*6.6*`"]
|
|
478
500
|
13{{"`#91;RNumber#93; 1
|
|
479
501
|
(13)
|
|
@@ -525,7 +547,7 @@ It offers a wide variety of features, for example:
|
|
|
525
547
|
*7.10-20*
|
|
526
548
|
(26, 27)`"]]
|
|
527
549
|
23["`#91;RSymbol#93; sum
|
|
528
|
-
(23, :may:36
|
|
550
|
+
(23, :may:36+, sources: [28])
|
|
529
551
|
*7.3-5*`"]
|
|
530
552
|
29[["`#91;RBinaryOp#93; #60;#45;
|
|
531
553
|
(29, :may:36+)
|
|
@@ -542,7 +564,7 @@ It offers a wide variety of features, for example:
|
|
|
542
564
|
*8.14-24*
|
|
543
565
|
(31, 32)`"]]
|
|
544
566
|
30["`#91;RSymbol#93; product
|
|
545
|
-
(30, :may:36
|
|
567
|
+
(30, :may:36+, sources: [33])
|
|
546
568
|
*8.3-9*`"]
|
|
547
569
|
34[["`#91;RBinaryOp#93; #60;#45;
|
|
548
570
|
(34, :may:36+)
|
|
@@ -712,7 +734,7 @@ It offers a wide variety of features, for example:
|
|
|
712
734
|
```
|
|
713
735
|
|
|
714
736
|
|
|
715
|
-
(The analysis required
|
|
737
|
+
(The analysis required _2.1 ms_ (including parse and normalize, using the [tree-sitter](https://github.com/flowr-analysis/flowr/wiki/Engines) engine) within the generation environment.)
|
|
716
738
|
|
|
717
739
|
|
|
718
740
|
|
|
@@ -889,7 +911,8 @@ We welcome every contribution! Please check out the [developer onboarding](https
|
|
|
889
911
|
|
|
890
912
|
*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
913
|
[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")
|
|
914
|
+
It is partially supported by the German Research Foundation (DFG) under the grant [504226141](https://gepris.dfg.de/gepris/projekt/504226141) ("CodeInspector")
|
|
915
|
+
and received an unrestricted gift from [Posit](https://posit.co/), the open-source data science company.
|
|
893
916
|
|
|
894
917
|
----
|
|
895
918
|
|
|
@@ -2,6 +2,7 @@ import type { ControlFlowInformation } from '../control-flow/control-flow-graph'
|
|
|
2
2
|
import { CfgVertex } from '../control-flow/control-flow-graph';
|
|
3
3
|
import type { SemanticCfgGuidedVisitorConfiguration } from '../control-flow/semantic-cfg-guided-visitor';
|
|
4
4
|
import { SemanticCfgGuidedVisitor } from '../control-flow/semantic-cfg-guided-visitor';
|
|
5
|
+
import { BuiltInProcName } from '../dataflow/environments/built-in-proc-name';
|
|
5
6
|
import type { DataflowGraph } from '../dataflow/graph/graph';
|
|
6
7
|
import { type DataflowGraphVertexFunctionCall, type DataflowGraphVertexVariableDefinition } from '../dataflow/graph/vertex';
|
|
7
8
|
import type { NoInfo, RNode } from '../r-bridge/lang-4.x/ast/model/model';
|
|
@@ -9,8 +10,6 @@ import type { NormalizedAst, ParentInformation } from '../r-bridge/lang-4.x/ast/
|
|
|
9
10
|
import type { NodeId } from '../r-bridge/lang-4.x/ast/model/processing/node-id';
|
|
10
11
|
import { type AnyAbstractDomain } from './domains/abstract-domain';
|
|
11
12
|
import type { StateAbstractDomain } from './domains/state-abstract-domain';
|
|
12
|
-
import { MutableStateAbstractDomain } from './domains/state-abstract-domain';
|
|
13
|
-
import { BuiltInProcName } from '../dataflow/environments/built-in-proc-name';
|
|
14
13
|
export type AbsintVisitorConfiguration = Omit<SemanticCfgGuidedVisitorConfiguration<NoInfo, ControlFlowInformation, NormalizedAst>, 'defaultVisitingOrder' | 'defaultVisitingType'>;
|
|
15
14
|
/**
|
|
16
15
|
* A control flow graph visitor to perform abstract interpretation.
|
|
@@ -24,20 +23,24 @@ export declare abstract class AbstractInterpretationVisitor<Domain extends AnyAb
|
|
|
24
23
|
/**
|
|
25
24
|
* The abstract trace of the abstract interpretation visitor mapping node IDs to the abstract state at the respective node.
|
|
26
25
|
*/
|
|
27
|
-
|
|
26
|
+
private readonly trace;
|
|
28
27
|
/**
|
|
29
28
|
* The current abstract state domain at the currently processed AST node.
|
|
30
29
|
*/
|
|
31
30
|
private _currentState;
|
|
32
|
-
/**
|
|
33
|
-
* A set of nodes representing variable definitions that have already been visited but whose assignment has not yet been processed.
|
|
34
|
-
*/
|
|
35
|
-
private readonly unassigned;
|
|
36
31
|
/**
|
|
37
32
|
* Whether the current abstract state has been copied/cloned and is save to modify in place.
|
|
38
33
|
*/
|
|
39
34
|
private stateCopied;
|
|
40
|
-
|
|
35
|
+
/**
|
|
36
|
+
* The current worklist stack of next vertex IDs to visit.
|
|
37
|
+
*/
|
|
38
|
+
private stack;
|
|
39
|
+
/**
|
|
40
|
+
* A set of nodes representing variable definitions that have already been visited but whose assignment has not yet been processed.
|
|
41
|
+
*/
|
|
42
|
+
private readonly unassigned;
|
|
43
|
+
constructor(config: Config, domain: Domain);
|
|
41
44
|
get currentState(): StateAbstractDomain<Domain>;
|
|
42
45
|
removeState(node: NodeId): void;
|
|
43
46
|
updateState(node: NodeId, value: Domain): void;
|
|
@@ -100,6 +103,8 @@ export declare abstract class AbstractInterpretationVisitor<Domain extends AnyAb
|
|
|
100
103
|
protected getPredecessorNodes(vertexId: NodeId): NodeId[];
|
|
101
104
|
/** Gets each variable origin that has already been visited and whose assignment has already been processed */
|
|
102
105
|
protected getVariableOrigins(nodeId: NodeId): NodeId[];
|
|
106
|
+
/** Checks whether a node represents a unsupported (environment-changing) function call (e.g. `eval`, `load`, `attach`, `rm`, ...) */
|
|
107
|
+
protected isUnsupportedFunctionCall(nodeId: NodeId): boolean;
|
|
103
108
|
/** We only perform widening at `for`, `while`, or `repeat` loops with more than one ingoing CFG edge */
|
|
104
109
|
protected isWideningPoint(nodeId: NodeId): boolean;
|
|
105
110
|
/**
|
|
@@ -3,6 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.AbstractInterpretationVisitor = void 0;
|
|
4
4
|
const control_flow_graph_1 = require("../control-flow/control-flow-graph");
|
|
5
5
|
const semantic_cfg_guided_visitor_1 = require("../control-flow/semantic-cfg-guided-visitor");
|
|
6
|
+
const built_in_proc_name_1 = require("../dataflow/environments/built-in-proc-name");
|
|
7
|
+
const df_helper_1 = require("../dataflow/graph/df-helper");
|
|
6
8
|
const vertex_1 = require("../dataflow/graph/vertex");
|
|
7
9
|
const model_1 = require("../r-bridge/lang-4.x/ast/model/model");
|
|
8
10
|
const r_function_call_1 = require("../r-bridge/lang-4.x/ast/model/nodes/r-function-call");
|
|
@@ -10,8 +12,7 @@ const type_1 = require("../r-bridge/lang-4.x/ast/model/type");
|
|
|
10
12
|
const assert_1 = require("../util/assert");
|
|
11
13
|
const abstract_domain_1 = require("./domains/abstract-domain");
|
|
12
14
|
const state_abstract_domain_1 = require("./domains/state-abstract-domain");
|
|
13
|
-
const
|
|
14
|
-
const built_in_proc_name_1 = require("../dataflow/environments/built-in-proc-name");
|
|
15
|
+
const unsupported_functions_1 = require("./unsupported-functions");
|
|
15
16
|
/**
|
|
16
17
|
* A control flow graph visitor to perform abstract interpretation.
|
|
17
18
|
*
|
|
@@ -26,17 +27,21 @@ class AbstractInterpretationVisitor extends semantic_cfg_guided_visitor_1.Semant
|
|
|
26
27
|
* The current abstract state domain at the currently processed AST node.
|
|
27
28
|
*/
|
|
28
29
|
_currentState;
|
|
29
|
-
/**
|
|
30
|
-
* A set of nodes representing variable definitions that have already been visited but whose assignment has not yet been processed.
|
|
31
|
-
*/
|
|
32
|
-
unassigned = new Set();
|
|
33
30
|
/**
|
|
34
31
|
* Whether the current abstract state has been copied/cloned and is save to modify in place.
|
|
35
32
|
*/
|
|
36
33
|
stateCopied = false;
|
|
37
|
-
|
|
34
|
+
/**
|
|
35
|
+
* The current worklist stack of next vertex IDs to visit.
|
|
36
|
+
*/
|
|
37
|
+
stack = [];
|
|
38
|
+
/**
|
|
39
|
+
* A set of nodes representing variable definitions that have already been visited but whose assignment has not yet been processed.
|
|
40
|
+
*/
|
|
41
|
+
unassigned = new Set();
|
|
42
|
+
constructor(config, domain) {
|
|
38
43
|
super({ ...config, defaultVisitingOrder: 'forward', defaultVisitingType: 'exit' });
|
|
39
|
-
this._currentState =
|
|
44
|
+
this._currentState = state_abstract_domain_1.MutableStateAbstractDomain.top(domain);
|
|
40
45
|
}
|
|
41
46
|
get currentState() {
|
|
42
47
|
return this._currentState;
|
|
@@ -125,7 +130,7 @@ class AbstractInterpretationVisitor extends semantic_cfg_guided_visitor_1.Semant
|
|
|
125
130
|
const exitPoints = this.config.controlFlow.exitPoints.map(id => this.getCfgVertex(id)).filter(assert_1.isNotUndefined);
|
|
126
131
|
const exitNodes = exitPoints.map(control_flow_graph_1.CfgVertex.getRootId).filter(assert_1.isNotUndefined);
|
|
127
132
|
const states = exitNodes.map(node => this.trace.get(node)).filter(assert_1.isNotUndefined);
|
|
128
|
-
return abstract_domain_1.AbstractDomain.joinAll(states, this._currentState.
|
|
133
|
+
return abstract_domain_1.AbstractDomain.joinAll(states, this._currentState.bottom());
|
|
129
134
|
}
|
|
130
135
|
/**
|
|
131
136
|
* Gets the inferred abstract trace mapping AST nodes to the inferred abstract state at the respective node.
|
|
@@ -140,15 +145,16 @@ class AbstractInterpretationVisitor extends semantic_cfg_guided_visitor_1.Semant
|
|
|
140
145
|
this.unassigned.clear();
|
|
141
146
|
}
|
|
142
147
|
startVisitor(start) {
|
|
143
|
-
|
|
144
|
-
while (stack.length > 0) {
|
|
145
|
-
const current = stack.pop();
|
|
148
|
+
this.stack = Array.from(start);
|
|
149
|
+
while (this.stack.length > 0) {
|
|
150
|
+
const current = this.stack.pop();
|
|
146
151
|
if (!this.visitNode(current)) {
|
|
147
152
|
continue;
|
|
148
153
|
}
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
154
|
+
const successors = this.config.controlFlow.graph.ingoingEdges(current)?.keys().toArray().reverse() ?? [];
|
|
155
|
+
for (const next of successors) {
|
|
156
|
+
if (!this.stack.includes(next)) { // prevent double entries in working list
|
|
157
|
+
this.stack.push(next);
|
|
152
158
|
}
|
|
153
159
|
}
|
|
154
160
|
}
|
|
@@ -162,18 +168,18 @@ class AbstractInterpretationVisitor extends semantic_cfg_guided_visitor_1.Semant
|
|
|
162
168
|
const predecessors = this.getPredecessorNodes(control_flow_graph_1.CfgVertex.getId(vertex));
|
|
163
169
|
const predecessorStates = predecessors.map(pred => this.trace.get(pred)).filter(assert_1.isNotUndefined);
|
|
164
170
|
// retrieve new abstract state by joining states of predecessor nodes
|
|
165
|
-
if (predecessorStates.length
|
|
166
|
-
this._currentState = predecessorStates[0];
|
|
171
|
+
if (predecessorStates.length <= 1) {
|
|
172
|
+
this._currentState = predecessorStates[0] ?? this._currentState.top();
|
|
167
173
|
}
|
|
168
174
|
else {
|
|
169
|
-
this._currentState = abstract_domain_1.AbstractDomain.joinAll(predecessorStates
|
|
175
|
+
this._currentState = abstract_domain_1.AbstractDomain.joinAll(predecessorStates);
|
|
170
176
|
this.stateCopied = true;
|
|
171
177
|
}
|
|
172
178
|
const nodeId = control_flow_graph_1.CfgVertex.getRootId(vertex);
|
|
173
179
|
// differentiate between widening points and other vertices
|
|
174
180
|
if (this.isWideningPoint(nodeId)) {
|
|
175
|
-
const oldState = this.trace.get(nodeId)
|
|
176
|
-
if (this.shouldWiden(vertex)) {
|
|
181
|
+
const oldState = this.trace.get(nodeId);
|
|
182
|
+
if (oldState !== undefined && this.shouldWiden(vertex)) {
|
|
177
183
|
this._currentState = oldState.widen(this._currentState);
|
|
178
184
|
this.stateCopied = true;
|
|
179
185
|
}
|
|
@@ -182,12 +188,12 @@ class AbstractInterpretationVisitor extends semantic_cfg_guided_visitor_1.Semant
|
|
|
182
188
|
const visitedCount = this.visited.get(nodeId) ?? 0;
|
|
183
189
|
this.visited.set(nodeId, visitedCount + 1);
|
|
184
190
|
// continue visiting after widening point if visited for the first time or the state changed
|
|
185
|
-
return visitedCount === 0 || !oldState
|
|
191
|
+
return visitedCount === 0 || !oldState?.equals(this._currentState);
|
|
186
192
|
}
|
|
187
193
|
else {
|
|
188
194
|
this.onVisitNode(vertexId);
|
|
189
|
-
// discard the inferred abstract state when encountering
|
|
190
|
-
if (this.
|
|
195
|
+
// discard the inferred abstract state when encountering unsupported function calls
|
|
196
|
+
if (this.isUnsupportedFunctionCall(nodeId)) {
|
|
191
197
|
this._currentState = this._currentState.top();
|
|
192
198
|
this.stateCopied = true;
|
|
193
199
|
}
|
|
@@ -197,7 +203,7 @@ class AbstractInterpretationVisitor extends semantic_cfg_guided_visitor_1.Semant
|
|
|
197
203
|
const visitedCount = this.visited.get(nodeId) ?? 0;
|
|
198
204
|
this.visited.set(nodeId, visitedCount + 1);
|
|
199
205
|
// continue visiting if vertex is not a join vertex or number of visits of predecessors is the same
|
|
200
|
-
return predecessors.length <= 1 || predecessorVisits.every(visits => visits === predecessorVisits[0]);
|
|
206
|
+
return predecessors.length <= 1 || this.stack.length === 0 || predecessorVisits.every(visits => visits === predecessorVisits[0]);
|
|
201
207
|
}
|
|
202
208
|
}
|
|
203
209
|
onDispatchFunctionCallOrigin(call, origin) {
|
|
@@ -278,14 +284,17 @@ class AbstractInterpretationVisitor extends semantic_cfg_guided_visitor_1.Semant
|
|
|
278
284
|
.map(origin => origin.id)
|
|
279
285
|
.filter(origin => this.trace.has(origin) && !this.unassigned.has(origin)) ?? [];
|
|
280
286
|
}
|
|
287
|
+
/** Checks whether a node represents a unsupported (environment-changing) function call (e.g. `eval`, `load`, `attach`, `rm`, ...) */
|
|
288
|
+
isUnsupportedFunctionCall(nodeId) {
|
|
289
|
+
return unsupported_functions_1.UnsupportedFunctions.isUnsupportedCall(this.getDataflowGraph(nodeId));
|
|
290
|
+
}
|
|
281
291
|
/** We only perform widening at `for`, `while`, or `repeat` loops with more than one ingoing CFG edge */
|
|
282
292
|
isWideningPoint(nodeId) {
|
|
283
293
|
const ingoingEdges = this.config.controlFlow.graph.outgoingEdges(nodeId)?.size; // outgoing dependency edges are ingoing CFG edges
|
|
284
294
|
if (ingoingEdges === undefined || ingoingEdges <= 1) {
|
|
285
295
|
return false;
|
|
286
296
|
}
|
|
287
|
-
|
|
288
|
-
if (model_1.RLoopConstructs.is(node)) {
|
|
297
|
+
else if (model_1.RLoopConstructs.is(this.getNormalizedAst(nodeId))) {
|
|
289
298
|
return true;
|
|
290
299
|
}
|
|
291
300
|
const dataflowVertex = this.getDataflowGraph(nodeId);
|
|
@@ -14,7 +14,6 @@ export type DataFrameShapeProperty<Property extends keyof AbstractDataFrameShape
|
|
|
14
14
|
* The data frame abstract domain as product domain of a column names domain, column count domain, and row count domain.
|
|
15
15
|
*/
|
|
16
16
|
export declare class DataFrameDomain extends ProductDomain<AbstractDataFrameShape> {
|
|
17
|
-
constructor(value: AbstractDataFrameShape);
|
|
18
17
|
create(value: AbstractDataFrameShape): this;
|
|
19
18
|
/**
|
|
20
19
|
* The current abstract value of the column names domain.
|
|
@@ -30,5 +29,5 @@ export declare class DataFrameDomain extends ProductDomain<AbstractDataFrameShap
|
|
|
30
29
|
get rows(): AbstractDataFrameShape['rows'];
|
|
31
30
|
static bottom(maxColNames?: number): DataFrameDomain;
|
|
32
31
|
static top(maxColNames?: number): DataFrameDomain;
|
|
33
|
-
|
|
32
|
+
protected reduce(value: AbstractDataFrameShape): AbstractDataFrameShape;
|
|
34
33
|
}
|
|
@@ -8,13 +8,6 @@ const set_range_domain_1 = require("../domains/set-range-domain");
|
|
|
8
8
|
* The data frame abstract domain as product domain of a column names domain, column count domain, and row count domain.
|
|
9
9
|
*/
|
|
10
10
|
class DataFrameDomain extends product_domain_1.ProductDomain {
|
|
11
|
-
constructor(value) {
|
|
12
|
-
super(DataFrameDomain.refine({
|
|
13
|
-
colnames: value.colnames.create(value.colnames.value),
|
|
14
|
-
cols: value.cols.create(value.cols.value),
|
|
15
|
-
rows: value.rows.create(value.rows.value)
|
|
16
|
-
}));
|
|
17
|
-
}
|
|
18
11
|
create(value) {
|
|
19
12
|
return new DataFrameDomain(value);
|
|
20
13
|
}
|
|
@@ -50,17 +43,23 @@ class DataFrameDomain extends product_domain_1.ProductDomain {
|
|
|
50
43
|
rows: positive_interval_domain_1.PosIntervalDomain.top()
|
|
51
44
|
});
|
|
52
45
|
}
|
|
53
|
-
|
|
46
|
+
reduce(value) {
|
|
54
47
|
if (value.colnames.isValue() && value.cols.isValue()) {
|
|
55
48
|
if (value.colnames.value.min.size >= value.cols.value[1]) {
|
|
56
|
-
value
|
|
49
|
+
value = {
|
|
50
|
+
...value,
|
|
51
|
+
colnames: value.colnames.meet({ min: new Set(), range: value.colnames.value.min })
|
|
52
|
+
};
|
|
57
53
|
}
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
54
|
+
}
|
|
55
|
+
if (value.colnames.isValue() && value.cols.isValue()) {
|
|
56
|
+
const minColNames = value.colnames.value.min.size;
|
|
57
|
+
const maxColNames = value.colnames.isFinite() ? value.colnames.value.min.size + value.colnames.value.range.size : Infinity;
|
|
58
|
+
if (minColNames > value.cols.value[0] || maxColNames < value.cols.value[1]) {
|
|
59
|
+
value = {
|
|
60
|
+
...value,
|
|
61
|
+
cols: value.cols.meet([minColNames, maxColNames])
|
|
62
|
+
};
|
|
64
63
|
}
|
|
65
64
|
}
|
|
66
65
|
return value;
|
|
@@ -3,17 +3,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.mapDataFrameAccess = mapDataFrameAccess;
|
|
4
4
|
exports.isStringBasedAccess = isStringBasedAccess;
|
|
5
5
|
const config_1 = require("../../../config");
|
|
6
|
+
const r_argument_1 = require("../../../r-bridge/lang-4.x/ast/model/nodes/r-argument");
|
|
6
7
|
const r_function_call_1 = require("../../../r-bridge/lang-4.x/ast/model/nodes/r-function-call");
|
|
7
8
|
const type_1 = require("../../../r-bridge/lang-4.x/ast/model/type");
|
|
8
9
|
const resolve_args_1 = require("../resolve-args");
|
|
9
10
|
const arguments_1 = require("./arguments");
|
|
10
|
-
/**
|
|
11
|
-
* Special named arguments of index-based access operators
|
|
12
|
-
*/
|
|
13
|
-
const SpecialAccessArgumentsMapper = {
|
|
14
|
-
'[': ['drop'],
|
|
15
|
-
'[[': ['exact']
|
|
16
|
-
};
|
|
17
11
|
/**
|
|
18
12
|
* Maps a concrete data frame access operation to abstract data frame operations.
|
|
19
13
|
* @param node - The R node of the access
|
|
@@ -50,7 +44,7 @@ function mapDataFrameIndexColRowAccess(access, inference, info) {
|
|
|
50
44
|
const dataFrame = access.accessed;
|
|
51
45
|
const drop = (0, arguments_1.getArgumentValue)(access.access, 'drop', info);
|
|
52
46
|
const exact = (0, arguments_1.getArgumentValue)(access.access, 'exact', info);
|
|
53
|
-
const args =
|
|
47
|
+
const args = access.access.filter(arg => r_argument_1.RArgument.isEmpty(arg) || r_argument_1.RArgument.isUnnamed(arg));
|
|
54
48
|
if (!(0, arguments_1.isDataFrameArgument)(dataFrame, inference)) {
|
|
55
49
|
return;
|
|
56
50
|
}
|
|
@@ -147,13 +141,6 @@ function mapDataFrameIndexColRowAccess(access, inference, info) {
|
|
|
147
141
|
}
|
|
148
142
|
return result;
|
|
149
143
|
}
|
|
150
|
-
/**
|
|
151
|
-
* Removes all special named arguments from the arguments of an access operator (i.e. arguments like "drop" and "exact").
|
|
152
|
-
*/
|
|
153
|
-
function getAccessArgs(operator, args) {
|
|
154
|
-
const specialArgs = SpecialAccessArgumentsMapper[operator];
|
|
155
|
-
return args.filter(arg => arg === r_function_call_1.EmptyArgument || arg.name === undefined || !specialArgs.includes((0, resolve_args_1.unquoteArgument)(arg.name.content)));
|
|
156
|
-
}
|
|
157
144
|
/**
|
|
158
145
|
* Checks whether an access node represents a string-based access (`$` or `@`), and no index-based access (`[` or `[[`).
|
|
159
146
|
*/
|