@eagleoutice/flowr 2.9.12 → 2.9.14
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 +35 -23
- package/abstract-interpretation/absint-visitor.d.ts +1 -1
- package/abstract-interpretation/absint-visitor.js +20 -20
- package/abstract-interpretation/data-frame/mappers/replacement-mapper.js +2 -2
- package/benchmark/slicer.d.ts +5 -3
- package/benchmark/slicer.js +26 -10
- package/benchmark/stats/print.js +12 -0
- package/benchmark/stats/stats.d.ts +3 -2
- package/benchmark/stats/stats.js +1 -1
- package/benchmark/summarizer/data.d.ts +1 -0
- package/benchmark/summarizer/second-phase/process.js +5 -0
- package/cli/benchmark-app.d.ts +1 -0
- package/cli/benchmark-app.js +1 -0
- package/cli/benchmark-helper-app.d.ts +2 -1
- package/cli/benchmark-helper-app.js +6 -3
- package/cli/common/options.d.ts +8 -0
- package/cli/common/options.js +3 -1
- package/cli/common/scripts-info.d.ts +8 -0
- package/cli/export-quads-app.js +1 -1
- package/cli/flowr.js +3 -3
- package/cli/repl/commands/repl-dataflow.js +5 -5
- package/cli/repl/core.d.ts +3 -3
- package/cli/repl/parser/slice-query-parser.d.ts +1 -1
- package/cli/repl/parser/slice-query-parser.js +2 -2
- package/cli/repl/server/connection.d.ts +2 -2
- package/cli/repl/server/connection.js +2 -2
- package/cli/repl/server/messages/message-slice.d.ts +1 -1
- package/cli/repl/server/messages/message-slice.js +2 -2
- package/cli/repl/server/server.d.ts +2 -2
- package/cli/script-core/statistics-core.d.ts +2 -2
- package/cli/script-core/statistics-helper-core.d.ts +2 -2
- package/cli/script-core/statistics-helper-core.js +1 -1
- package/cli/slicer-app.js +2 -2
- package/cli/statistics-app.js +1 -1
- package/cli/statistics-helper-app.js +1 -1
- package/cli/wiki.js +2 -2
- package/config.d.ts +65 -24
- package/config.js +197 -161
- package/control-flow/extract-cfg.js +7 -10
- package/control-flow/semantic-cfg-guided-visitor.d.ts +1 -1
- package/control-flow/semantic-cfg-guided-visitor.js +43 -43
- package/control-flow/useless-loop.d.ts +1 -1
- package/control-flow/useless-loop.js +3 -3
- package/core/print/dataflow-printer.d.ts +0 -14
- package/core/print/dataflow-printer.js +0 -21
- package/core/steps/all/core/20-dataflow.d.ts +3 -3
- package/core/steps/all/core/20-dataflow.js +3 -2
- package/core/steps/all/static-slicing/00-slice.d.ts +2 -5
- package/core/steps/all/static-slicing/00-slice.js +6 -8
- package/core/steps/pipeline/default-pipelines.d.ts +89 -89
- package/core/steps/pipeline-step.d.ts +2 -2
- package/dataflow/environments/built-in-proc-name.d.ts +83 -0
- package/dataflow/environments/built-in-proc-name.js +88 -0
- package/dataflow/environments/built-in.d.ts +1 -83
- package/dataflow/environments/built-in.js +37 -120
- package/dataflow/environments/default-builtin-config.d.ts +1 -1
- package/dataflow/environments/default-builtin-config.js +75 -75
- package/dataflow/environments/identifier.d.ts +1 -0
- package/dataflow/environments/identifier.js +1 -0
- package/dataflow/eval/resolve/alias-tracking.js +12 -15
- package/dataflow/eval/resolve/resolve.js +2 -2
- package/dataflow/fn/exceptions-of-function.d.ts +1 -1
- package/dataflow/fn/exceptions-of-function.js +2 -2
- package/dataflow/graph/call-graph.d.ts +49 -19
- package/dataflow/graph/call-graph.js +117 -114
- package/dataflow/graph/dataflowgraph-builder.d.ts +1 -1
- package/dataflow/graph/dataflowgraph-builder.js +2 -2
- package/dataflow/graph/df-helper.d.ts +132 -0
- package/dataflow/graph/df-helper.js +131 -0
- package/dataflow/graph/diff-dataflow-graph.d.ts +5 -10
- package/dataflow/graph/diff-dataflow-graph.js +3 -28
- package/dataflow/graph/edge.d.ts +1 -0
- package/dataflow/graph/edge.js +1 -0
- package/dataflow/graph/graph-helper.d.ts +55 -0
- package/dataflow/graph/graph-helper.js +105 -0
- package/dataflow/graph/graph.d.ts +6 -1
- package/dataflow/graph/graph.js +14 -9
- package/dataflow/graph/vertex.d.ts +1 -1
- package/dataflow/info.d.ts +14 -4
- package/dataflow/info.js +28 -16
- package/dataflow/internal/linker.d.ts +14 -10
- package/dataflow/internal/linker.js +29 -32
- package/dataflow/internal/process/functions/call/built-in/built-in-access.js +5 -5
- package/dataflow/internal/process/functions/call/built-in/built-in-apply.js +4 -4
- package/dataflow/internal/process/functions/call/built-in/built-in-assignment.js +7 -6
- package/dataflow/internal/process/functions/call/built-in/built-in-eval.d.ts +1 -1
- package/dataflow/internal/process/functions/call/built-in/built-in-eval.js +5 -5
- package/dataflow/internal/process/functions/call/built-in/built-in-expression-list.js +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-for-loop.js +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-function-definition.js +4 -4
- package/dataflow/internal/process/functions/call/built-in/built-in-get.js +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-if-then-else.js +3 -3
- package/dataflow/internal/process/functions/call/built-in/built-in-library.js +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-list.js +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-local.d.ts +1 -1
- package/dataflow/internal/process/functions/call/built-in/built-in-local.js +5 -5
- package/dataflow/internal/process/functions/call/built-in/built-in-pipe.js +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-quote.js +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-recall.js +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-register-hook.js +5 -5
- package/dataflow/internal/process/functions/call/built-in/built-in-repeat-loop.js +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-replacement.d.ts +1 -1
- package/dataflow/internal/process/functions/call/built-in/built-in-replacement.js +5 -4
- package/dataflow/internal/process/functions/call/built-in/built-in-rm.js +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-s-seven-dispatch.js +3 -3
- package/dataflow/internal/process/functions/call/built-in/built-in-s-seven-new-generic.js +3 -3
- package/dataflow/internal/process/functions/call/built-in/built-in-s-three-dispatch.d.ts +1 -1
- package/dataflow/internal/process/functions/call/built-in/built-in-s-three-dispatch.js +7 -7
- 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-source.js +23 -12
- package/dataflow/internal/process/functions/call/built-in/built-in-special-bin-op.js +3 -3
- package/dataflow/internal/process/functions/call/built-in/built-in-stop-if-not.js +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-try-catch.js +6 -9
- package/dataflow/internal/process/functions/call/built-in/built-in-vector.js +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-while-loop.js +2 -2
- package/dataflow/internal/process/functions/call/known-call-handling.js +2 -2
- package/dataflow/internal/process/functions/call/named-call-handling.d.ts +1 -1
- package/dataflow/internal/process/functions/call/named-call-handling.js +1 -1
- package/dataflow/internal/process/functions/call/unnamed-call-handling.js +2 -2
- package/dataflow/internal/process/process-uninteresting-leaf.d.ts +1 -1
- package/dataflow/internal/process/process-uninteresting-leaf.js +1 -1
- package/dataflow/origin/dfg-get-origin.d.ts +1 -1
- package/dataflow/origin/dfg-get-symbol-refs.js +6 -6
- package/documentation/doc-readme.js +2 -2
- package/documentation/doc-util/doc-dfg.d.ts +3 -0
- package/documentation/doc-util/doc-dfg.js +5 -7
- package/documentation/doc-util/doc-normalized-ast.d.ts +0 -6
- package/documentation/doc-util/doc-normalized-ast.js +0 -23
- package/documentation/doc-util/doc-structure.js +3 -3
- package/documentation/doc-util/doc-types.js +3 -3
- package/documentation/wiki-analyzer.js +7 -5
- package/documentation/wiki-core.js +6 -7
- package/documentation/wiki-dataflow-graph.js +15 -13
- package/documentation/wiki-interface.js +8 -6
- package/documentation/wiki-linter.js +6 -5
- package/documentation/wiki-mk/doc-context.js +3 -4
- package/documentation/wiki-normalized-ast.js +5 -4
- package/documentation/wiki-query.js +28 -3
- package/engines.d.ts +2 -2
- package/engines.js +4 -4
- package/linter/linter-rules.d.ts +24 -1
- package/linter/linter-rules.js +3 -1
- package/linter/rules/dataframe-access-validation.js +5 -5
- package/linter/rules/naming-convention.d.ts +1 -1
- package/linter/rules/naming-convention.js +7 -3
- package/linter/rules/seeded-randomness.js +2 -2
- package/linter/rules/stop-with-call-arg.d.ts +35 -0
- package/linter/rules/stop-with-call-arg.js +72 -0
- package/linter/rules/useless-loop.d.ts +1 -1
- package/package.json +3 -1
- package/project/cache/flowr-analyzer-cache.d.ts +1 -1
- package/project/cache/flowr-analyzer-cache.js +1 -1
- package/project/context/flowr-analyzer-context.d.ts +6 -6
- package/project/context/flowr-analyzer-context.js +2 -2
- package/project/context/flowr-analyzer-files-context.d.ts +2 -2
- package/project/context/flowr-analyzer-files-context.js +28 -8
- package/project/flowr-analyzer-builder.d.ts +13 -6
- package/project/flowr-analyzer-builder.js +12 -3
- package/project/flowr-analyzer.d.ts +4 -4
- package/queries/catalog/call-context-query/identify-link-to-nested-call-relation.js +2 -2
- package/queries/catalog/call-graph-query/call-graph-query-format.d.ts +1 -1
- package/queries/catalog/call-graph-query/call-graph-query-format.js +2 -2
- package/queries/catalog/cluster-query/cluster-query-format.js +2 -2
- package/queries/catalog/config-query/config-query-format.d.ts +5 -5
- package/queries/catalog/dataflow-lens-query/dataflow-lens-query-format.js +2 -2
- package/queries/catalog/dataflow-query/dataflow-query-format.js +2 -2
- package/queries/catalog/df-shape-query/df-shape-query-executor.js +1 -2
- package/queries/catalog/df-shape-query/df-shape-query-format.d.ts +2 -2
- package/queries/catalog/does-call-query/does-call-query-executor.js +2 -2
- package/queries/catalog/does-call-query/does-call-query-format.d.ts +2 -2
- package/queries/catalog/files-query/files-query-format.d.ts +3 -3
- package/queries/catalog/happens-before-query/happens-before-query-executor.js +2 -2
- package/queries/catalog/inspect-exceptions-query/inspect-exception-query-executor.d.ts +1 -1
- 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 +3 -3
- 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/linter-query/linter-query-format.d.ts +3 -3
- package/queries/catalog/location-map-query/location-map-query-executor.js +2 -2
- package/queries/catalog/location-map-query/location-map-query-format.d.ts +2 -2
- package/queries/catalog/origin-query/origin-query-executor.d.ts +1 -1
- package/queries/catalog/origin-query/origin-query-executor.js +3 -3
- package/queries/catalog/origin-query/origin-query-format.d.ts +2 -2
- package/queries/catalog/provenance-query/provenance-query-executor.d.ts +9 -0
- package/queries/catalog/provenance-query/provenance-query-executor.js +37 -0
- package/queries/catalog/provenance-query/provenance-query-format.d.ts +35 -0
- package/queries/catalog/provenance-query/provenance-query-format.js +62 -0
- package/queries/catalog/resolve-value-query/resolve-value-query-executor.js +4 -4
- package/queries/catalog/resolve-value-query/resolve-value-query-format.d.ts +2 -2
- package/queries/catalog/resolve-value-query/resolve-value-query-format.js +4 -0
- package/queries/catalog/search-query/search-query-format.js +1 -1
- package/queries/catalog/static-slice-query/static-slice-query-executor.js +4 -2
- package/queries/catalog/static-slice-query/static-slice-query-format.d.ts +4 -4
- package/queries/catalog/static-slice-query/static-slice-query-format.js +3 -3
- package/queries/query.d.ts +27 -19
- package/queries/query.js +2 -0
- package/r-bridge/lang-4.x/ast/model/model.d.ts +13 -2
- package/r-bridge/lang-4.x/ast/model/model.js +20 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-function-definition.d.ts +8 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-function-definition.js +13 -0
- package/r-bridge/lang-4.x/ast/parser/json/parser.d.ts +2 -2
- package/r-bridge/lang-4.x/ast/parser/json/parser.js +2 -2
- package/r-bridge/lang-4.x/tree-sitter/tree-sitter-normalize.js +6 -2
- package/search/flowr-search-filters.d.ts +1 -1
- package/search/flowr-search-printer.js +3 -3
- package/search/search-executor/search-enrichers.js +2 -2
- package/search/search-executor/search-generators.js +1 -1
- package/slicing/criterion/parse.d.ts +40 -16
- package/slicing/criterion/parse.js +67 -63
- package/slicing/static/slicer-types.d.ts +2 -3
- package/slicing/static/static-slicer.d.ts +3 -4
- package/slicing/static/static-slicer.js +9 -12
- package/statistics/statistics.d.ts +2 -2
- package/util/diff.d.ts +2 -2
- package/util/mermaid/ast.js +4 -4
- package/util/mermaid/cfg.js +5 -5
- package/util/mermaid/dfg.d.ts +33 -18
- package/util/mermaid/dfg.js +46 -31
- package/util/mermaid/mermaid.d.ts +57 -12
- package/util/mermaid/mermaid.js +74 -67
- package/util/objects.d.ts +12 -0
- package/util/objects.js +28 -0
- package/util/range.d.ts +8 -0
- package/util/range.js +13 -1
- package/util/slice-direction.d.ts +7 -0
- package/util/slice-direction.js +12 -0
- package/util/summarizer.js +1 -1
- package/util/version.js +1 -1
- package/dataflow/graph/invert-dfg.d.ts +0 -6
- package/dataflow/graph/invert-dfg.js +0 -20
- package/dataflow/graph/resolve-graph.d.ts +0 -8
- package/dataflow/graph/resolve-graph.js +0 -59
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.9.
|
|
27
|
+
flowR repl using flowR v2.9.13, R grammar v14 (tree-sitter engine)
|
|
28
28
|
R> :query @linter "read.csv(\"/root/x.txt\")"
|
|
29
29
|
```
|
|
30
30
|
|
|
@@ -35,11 +35,11 @@ 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: 0, 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: 1, 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):
|
|
@@ -58,6 +58,8 @@ It offers a wide variety of features, for example:
|
|
|
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
|
+
╰ Stop without call.=False argument (stop-call):
|
|
62
|
+
╰ Metadata: consideredNodes: 0, searchTimeMs: 0, processTimeMs: 0
|
|
61
63
|
All queries together required ≈2 ms (1ms accuracy, total 2 ms)
|
|
62
64
|
```
|
|
63
65
|
|
|
@@ -82,17 +84,17 @@ It offers a wide variety of features, for example:
|
|
|
82
84
|
|
|
83
85
|
Query: **linter** (2 ms)\
|
|
84
86
|
╰ **Deprecated Functions** (deprecated-functions):\
|
|
85
|
-
╰ _Metadata_: <code>totalCalls: 0, totalFunctionDefinitions: 0, searchTimeMs:
|
|
87
|
+
╰ _Metadata_: <code>totalCalls: 0, totalFunctionDefinitions: 0, searchTimeMs: 0, processTimeMs: 0</code>\
|
|
86
88
|
╰ **File Path Validity** (file-path-validity):\
|
|
87
89
|
╰ certain:\
|
|
88
90
|
╰ Path `/root/x.txt` at 1.1-23\
|
|
89
|
-
╰ _Metadata_: <code>totalReads: 1, totalUnknown: 0, totalWritesBeforeAlways: 0, totalValid: 0, searchTimeMs:
|
|
91
|
+
╰ _Metadata_: <code>totalReads: 1, totalUnknown: 0, totalWritesBeforeAlways: 0, totalValid: 0, searchTimeMs: 1, processTimeMs: 0</code>\
|
|
90
92
|
╰ **Seeded Randomness** (seeded-randomness):\
|
|
91
93
|
╰ _Metadata_: <code>consumerCalls: 0, callsWithFunctionProducers: 0, callsWithAssignmentProducers: 0, callsWithNonConstantProducers: 0, callsWithOtherBranchProducers: 0, searchTimeMs: 0, processTimeMs: 0</code>\
|
|
92
94
|
╰ **Absolute Paths** (absolute-file-paths):\
|
|
93
95
|
╰ certain:\
|
|
94
96
|
╰ Path `/root/x.txt` at 1.1-23\
|
|
95
|
-
╰ _Metadata_: <code>totalConsidered: 1, totalUnknown: 0, searchTimeMs:
|
|
97
|
+
╰ _Metadata_: <code>totalConsidered: 1, totalUnknown: 0, searchTimeMs: 0, processTimeMs: 0</code>\
|
|
96
98
|
╰ **Unused Definitions** (unused-definitions):\
|
|
97
99
|
╰ _Metadata_: <code>totalConsidered: 0, searchTimeMs: 0, processTimeMs: 0</code>\
|
|
98
100
|
╰ **Naming Convention** (naming-convention):\
|
|
@@ -100,16 +102,18 @@ It offers a wide variety of features, for example:
|
|
|
100
102
|
╰ **Network Functions** (network-functions):\
|
|
101
103
|
╰ _Metadata_: <code>totalCalls: 0, totalFunctionDefinitions: 0, searchTimeMs: 0, processTimeMs: 0</code>\
|
|
102
104
|
╰ **Dataframe Access Validation** (dataframe-access-validation):\
|
|
103
|
-
╰ _Metadata_: <code>numOperations: 0, numAccesses: 0, totalAccessed: 0, searchTimeMs: 0, processTimeMs:
|
|
105
|
+
╰ _Metadata_: <code>numOperations: 0, numAccesses: 0, totalAccessed: 0, searchTimeMs: 0, processTimeMs: 1</code>\
|
|
104
106
|
╰ **Dead Code** (dead-code):\
|
|
105
107
|
╰ _Metadata_: <code>consideredNodes: 5, searchTimeMs: 0, processTimeMs: 0</code>\
|
|
106
108
|
╰ **Useless Loops** (useless-loop):\
|
|
107
109
|
╰ _Metadata_: <code>numOfUselessLoops: 0, searchTimeMs: 0, processTimeMs: 0</code>\
|
|
110
|
+
╰ **Stop without call.=False argument** (stop-call):\
|
|
111
|
+
╰ _Metadata_: <code>consideredNodes: 0, searchTimeMs: 0, processTimeMs: 0</code>\
|
|
108
112
|
_All queries together required ≈2 ms (1ms accuracy, total 2 ms)_
|
|
109
113
|
|
|
110
114
|
<details> <summary style="color:gray">Show Detailed Results as Json</summary>
|
|
111
115
|
|
|
112
|
-
The analysis required _2.
|
|
116
|
+
The analysis required _2.3 ms_ (including parsing and normalization and the query) within the generation environment.
|
|
113
117
|
|
|
114
118
|
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.
|
|
115
119
|
Please consult the [Interface](https://github.com/flowr-analysis/flowr/wiki/Interface) wiki page for more information on how to get those.
|
|
@@ -126,7 +130,7 @@ It offers a wide variety of features, for example:
|
|
|
126
130
|
".meta": {
|
|
127
131
|
"totalCalls": 0,
|
|
128
132
|
"totalFunctionDefinitions": 0,
|
|
129
|
-
"searchTimeMs":
|
|
133
|
+
"searchTimeMs": 0,
|
|
130
134
|
"processTimeMs": 0
|
|
131
135
|
}
|
|
132
136
|
},
|
|
@@ -149,7 +153,7 @@ It offers a wide variety of features, for example:
|
|
|
149
153
|
"totalUnknown": 0,
|
|
150
154
|
"totalWritesBeforeAlways": 0,
|
|
151
155
|
"totalValid": 0,
|
|
152
|
-
"searchTimeMs":
|
|
156
|
+
"searchTimeMs": 1,
|
|
153
157
|
"processTimeMs": 0
|
|
154
158
|
}
|
|
155
159
|
},
|
|
@@ -181,7 +185,7 @@ It offers a wide variety of features, for example:
|
|
|
181
185
|
".meta": {
|
|
182
186
|
"totalConsidered": 1,
|
|
183
187
|
"totalUnknown": 0,
|
|
184
|
-
"searchTimeMs":
|
|
188
|
+
"searchTimeMs": 0,
|
|
185
189
|
"processTimeMs": 0
|
|
186
190
|
}
|
|
187
191
|
},
|
|
@@ -218,7 +222,7 @@ It offers a wide variety of features, for example:
|
|
|
218
222
|
"numAccesses": 0,
|
|
219
223
|
"totalAccessed": 0,
|
|
220
224
|
"searchTimeMs": 0,
|
|
221
|
-
"processTimeMs":
|
|
225
|
+
"processTimeMs": 1
|
|
222
226
|
}
|
|
223
227
|
},
|
|
224
228
|
"dead-code": {
|
|
@@ -236,6 +240,14 @@ It offers a wide variety of features, for example:
|
|
|
236
240
|
"searchTimeMs": 0,
|
|
237
241
|
"processTimeMs": 0
|
|
238
242
|
}
|
|
243
|
+
},
|
|
244
|
+
"stop-call": {
|
|
245
|
+
"results": [],
|
|
246
|
+
".meta": {
|
|
247
|
+
"consideredNodes": 0,
|
|
248
|
+
"searchTimeMs": 0,
|
|
249
|
+
"processTimeMs": 0
|
|
250
|
+
}
|
|
239
251
|
}
|
|
240
252
|
},
|
|
241
253
|
".meta": {
|
|
@@ -308,7 +320,7 @@ It offers a wide variety of features, for example:
|
|
|
308
320
|
|
|
309
321
|
```shell
|
|
310
322
|
$ docker run -it --rm eagleoutice/flowr # or npm run flowr
|
|
311
|
-
flowR repl using flowR v2.9.
|
|
323
|
+
flowR repl using flowR v2.9.13, R grammar v14 (tree-sitter engine)
|
|
312
324
|
R> :query @static-slice (11@sum) file://test/testfiles/example.R
|
|
313
325
|
```
|
|
314
326
|
|
|
@@ -322,7 +334,7 @@ It offers a wide variety of features, for example:
|
|
|
322
334
|
N <- 10
|
|
323
335
|
for(i in 1:(N-1)) sum <- sum + i + w
|
|
324
336
|
sum
|
|
325
|
-
All queries together required ≈
|
|
337
|
+
All queries together required ≈1 ms (1ms accuracy, total 2 ms)
|
|
326
338
|
```
|
|
327
339
|
|
|
328
340
|
|
|
@@ -338,7 +350,7 @@ It offers a wide variety of features, for example:
|
|
|
338
350
|
|
|
339
351
|
|
|
340
352
|
* 📚 **dependency analysis**\
|
|
341
|
-
Given your analysis project, flowR offers a plethora of so-called [queries](https://github.com/flowr-analysis/flowr/wiki/
|
|
353
|
+
Given your analysis project, flowR offers a plethora of so-called [queries](https://github.com/flowr-analysis/flowr/wiki/query-api) to get more information about your code.
|
|
342
354
|
An important query is the [dependencies query](https://github.com/flowr-analysis/flowr/wiki/Query-API#dependencies-query), which shows you the library your project needs,
|
|
343
355
|
the data files it reads, the scripts it sources, and the data it outputs.
|
|
344
356
|
|
|
@@ -356,16 +368,16 @@ It offers a wide variety of features, for example:
|
|
|
356
368
|
|
|
357
369
|
|
|
358
370
|
* 🚀 **fast call-graph, data-, and control-flow graphs**\
|
|
359
|
-
Within just [<i><span title="This measurement is automatically fetched from the latest benchmark!">
|
|
371
|
+
Within just [<i><span title="This measurement is automatically fetched from the latest benchmark!">101.1 ms</span></i> (as of Feb 28, 2026)](https://flowr-analysis.github.io/flowr/wiki/stats/benchmark),
|
|
360
372
|
_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,
|
|
361
|
-
and consult the [wiki pages](https://github.com/flowr-analysis/flowr/wiki/
|
|
373
|
+
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).
|
|
362
374
|
|
|
363
375
|
|
|
364
376
|
<details><summary>Example: Generating a dataflow graph with flowR</summary>
|
|
365
377
|
|
|
366
378
|
|
|
367
379
|
You can investigate flowR's analyses using the [REPL](https://github.com/flowr-analysis/flowr/wiki/Interface#using-the-repl).
|
|
368
|
-
Commands like <span title="Description (Repl Command, starred version): Returns the URL to mermaid.live; Base Command: Get mermaid code for the dataflow graph, start with 'file://' to indicate a file (aliases: :d*, :df*)">`:dataflow*`</span> allow you to view a [dataflow graph](https://github.com/flowr-analysis/flowr/wiki/
|
|
380
|
+
Commands like <span title="Description (Repl Command, starred version): Returns the URL to mermaid.live; Base Command: Get mermaid code for the dataflow graph, start with 'file://' to indicate a file (aliases: :d*, :df*)">`:dataflow*`</span> allow you to view a [dataflow graph](https://github.com/flowr-analysis/flowr/wiki/dataflow-graph) for a given R script.
|
|
369
381
|
|
|
370
382
|
Let's have a look at the following example:
|
|
371
383
|
|
|
@@ -386,13 +398,13 @@ It offers a wide variety of features, for example:
|
|
|
386
398
|
```
|
|
387
399
|
|
|
388
400
|
|
|
389
|
-
To get the [dataflow graph](https://github.com/flowr-analysis/flowr/wiki/
|
|
401
|
+
To get the [dataflow graph](https://github.com/flowr-analysis/flowr/wiki/dataflow-graph) for this script, you can use the following command:
|
|
390
402
|
|
|
391
403
|
|
|
392
404
|
|
|
393
405
|
```shell
|
|
394
406
|
$ docker run -it --rm eagleoutice/flowr # or npm run flowr
|
|
395
|
-
flowR repl using flowR v2.9.
|
|
407
|
+
flowR repl using flowR v2.9.13, R grammar v14 (tree-sitter engine)
|
|
396
408
|
R> :dataflow* test/testfiles/example.R
|
|
397
409
|
```
|
|
398
410
|
|
|
@@ -727,8 +739,8 @@ If you are already using flowR and want to give feedback, please consider fillin
|
|
|
727
739
|
|
|
728
740
|
## ⭐ Getting Started
|
|
729
741
|
|
|
730
|
-
To get started with _flowR_ and its features, please check out the [Overview](https://github.com/flowr-analysis/flowr/wiki/
|
|
731
|
-
The [Setup](https://github.com/flowr-analysis/flowr/wiki/
|
|
742
|
+
To get started with _flowR_ and its features, please check out the [Overview](https://github.com/flowr-analysis/flowr/wiki/overview) wiki page.
|
|
743
|
+
The [Setup](https://github.com/flowr-analysis/flowr/wiki/setup) wiki page explains how you can download and setup _flowR_ on your system.
|
|
732
744
|
With docker 🐳️, the following line should be enough (and drop you directly into the read-eval-print loop):
|
|
733
745
|
|
|
734
746
|
|
|
@@ -865,7 +877,7 @@ please check out the following publications (if you find that a paper is missing
|
|
|
865
877
|
|
|
866
878
|
## 🚀 Contributing
|
|
867
879
|
|
|
868
|
-
We welcome every contribution! Please check out the [developer onboarding](https://github.com/flowr-analysis/flowr/wiki/
|
|
880
|
+
We welcome every contribution! Please check out the [developer onboarding](https://github.com/flowr-analysis/flowr/wiki/onboarding) section in the wiki for all the information you will need.
|
|
869
881
|
|
|
870
882
|
### Contributors
|
|
871
883
|
|
|
@@ -2,7 +2,6 @@ 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';
|
|
6
5
|
import type { DataflowGraph } from '../dataflow/graph/graph';
|
|
7
6
|
import { type DataflowGraphVertexFunctionCall, type DataflowGraphVertexVariableDefinition } from '../dataflow/graph/vertex';
|
|
8
7
|
import type { NoInfo, RNode } from '../r-bridge/lang-4.x/ast/model/model';
|
|
@@ -11,6 +10,7 @@ import type { NodeId } from '../r-bridge/lang-4.x/ast/model/processing/node-id';
|
|
|
11
10
|
import { type AnyAbstractDomain } from './domains/abstract-domain';
|
|
12
11
|
import type { StateAbstractDomain } from './domains/state-abstract-domain';
|
|
13
12
|
import { MutableStateAbstractDomain } from './domains/state-abstract-domain';
|
|
13
|
+
import { BuiltInProcName } from '../dataflow/environments/built-in-proc-name';
|
|
14
14
|
export type AbsintVisitorConfiguration = Omit<SemanticCfgGuidedVisitorConfiguration<NoInfo, ControlFlowInformation, NormalizedAst>, 'defaultVisitingOrder' | 'defaultVisitingType'>;
|
|
15
15
|
/**
|
|
16
16
|
* A control flow graph visitor to perform abstract interpretation.
|
|
@@ -3,15 +3,15 @@ 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_1 = require("../dataflow/environments/built-in");
|
|
7
6
|
const vertex_1 = require("../dataflow/graph/vertex");
|
|
8
|
-
const dfg_get_origin_1 = require("../dataflow/origin/dfg-get-origin");
|
|
9
7
|
const model_1 = require("../r-bridge/lang-4.x/ast/model/model");
|
|
10
8
|
const r_function_call_1 = require("../r-bridge/lang-4.x/ast/model/nodes/r-function-call");
|
|
11
9
|
const type_1 = require("../r-bridge/lang-4.x/ast/model/type");
|
|
12
10
|
const assert_1 = require("../util/assert");
|
|
13
11
|
const abstract_domain_1 = require("./domains/abstract-domain");
|
|
14
12
|
const state_abstract_domain_1 = require("./domains/state-abstract-domain");
|
|
13
|
+
const df_helper_1 = require("../dataflow/graph/df-helper");
|
|
14
|
+
const built_in_proc_name_1 = require("../dataflow/environments/built-in-proc-name");
|
|
15
15
|
/**
|
|
16
16
|
* A control flow graph visitor to perform abstract interpretation.
|
|
17
17
|
*
|
|
@@ -86,7 +86,7 @@ class AbstractInterpretationVisitor extends semantic_cfg_guided_visitor_1.Semant
|
|
|
86
86
|
else if (node.type === type_1.RType.ExpressionList && node.children.length > 0) {
|
|
87
87
|
return this.getAbstractValue(node.children.at(-1), state);
|
|
88
88
|
}
|
|
89
|
-
else if (origins.includes(
|
|
89
|
+
else if (origins.includes(built_in_proc_name_1.BuiltInProcName.Pipe)) {
|
|
90
90
|
if (node.type === type_1.RType.Pipe || node.type === type_1.RType.BinaryOp) {
|
|
91
91
|
return this.getAbstractValue(node.rhs, state);
|
|
92
92
|
}
|
|
@@ -94,7 +94,7 @@ class AbstractInterpretationVisitor extends semantic_cfg_guided_visitor_1.Semant
|
|
|
94
94
|
return this.getAbstractValue(call.args[1].nodeId, state);
|
|
95
95
|
}
|
|
96
96
|
}
|
|
97
|
-
else if (origins.includes(
|
|
97
|
+
else if (origins.includes(built_in_proc_name_1.BuiltInProcName.IfThenElse)) {
|
|
98
98
|
let values = [];
|
|
99
99
|
if (node.type === type_1.RType.IfThenElse && node.otherwise !== undefined) {
|
|
100
100
|
values = [node.then, node.otherwise].map(entry => this.getAbstractValue(entry, state));
|
|
@@ -203,20 +203,20 @@ class AbstractInterpretationVisitor extends semantic_cfg_guided_visitor_1.Semant
|
|
|
203
203
|
onDispatchFunctionCallOrigin(call, origin) {
|
|
204
204
|
super.onDispatchFunctionCallOrigin(call, origin);
|
|
205
205
|
switch (origin) {
|
|
206
|
-
case
|
|
207
|
-
case
|
|
208
|
-
case
|
|
209
|
-
case
|
|
210
|
-
case
|
|
211
|
-
case
|
|
212
|
-
case
|
|
213
|
-
case
|
|
214
|
-
case
|
|
215
|
-
case
|
|
216
|
-
case
|
|
217
|
-
case
|
|
218
|
-
case
|
|
219
|
-
case
|
|
206
|
+
case built_in_proc_name_1.BuiltInProcName.ExpressionList:
|
|
207
|
+
case built_in_proc_name_1.BuiltInProcName.IfThenElse:
|
|
208
|
+
case built_in_proc_name_1.BuiltInProcName.ForLoop:
|
|
209
|
+
case built_in_proc_name_1.BuiltInProcName.WhileLoop:
|
|
210
|
+
case built_in_proc_name_1.BuiltInProcName.RepeatLoop:
|
|
211
|
+
case built_in_proc_name_1.BuiltInProcName.FunctionDefinition:
|
|
212
|
+
case built_in_proc_name_1.BuiltInProcName.Assignment:
|
|
213
|
+
case built_in_proc_name_1.BuiltInProcName.AssignmentLike:
|
|
214
|
+
case built_in_proc_name_1.BuiltInProcName.TableAssignment:
|
|
215
|
+
case built_in_proc_name_1.BuiltInProcName.Replacement:
|
|
216
|
+
case built_in_proc_name_1.BuiltInProcName.Access:
|
|
217
|
+
case built_in_proc_name_1.BuiltInProcName.Pipe:
|
|
218
|
+
case built_in_proc_name_1.BuiltInProcName.Break:
|
|
219
|
+
case built_in_proc_name_1.BuiltInProcName.Return:
|
|
220
220
|
return;
|
|
221
221
|
default:
|
|
222
222
|
return this.onFunctionCall({ call });
|
|
@@ -273,7 +273,7 @@ class AbstractInterpretationVisitor extends semantic_cfg_guided_visitor_1.Semant
|
|
|
273
273
|
}
|
|
274
274
|
/** Gets each variable origin that has already been visited and whose assignment has already been processed */
|
|
275
275
|
getVariableOrigins(nodeId) {
|
|
276
|
-
return
|
|
276
|
+
return df_helper_1.Dataflow.origin(this.config.dfg, nodeId)
|
|
277
277
|
?.filter(origin => origin.type === 0 /* OriginType.ReadVariableOrigin */)
|
|
278
278
|
.map(origin => origin.id)
|
|
279
279
|
.filter(origin => this.trace.has(origin) && !this.unassigned.has(origin)) ?? [];
|
|
@@ -293,7 +293,7 @@ class AbstractInterpretationVisitor extends semantic_cfg_guided_visitor_1.Semant
|
|
|
293
293
|
return false;
|
|
294
294
|
}
|
|
295
295
|
const origin = dataflowVertex.origin;
|
|
296
|
-
return origin.includes(
|
|
296
|
+
return origin.includes(built_in_proc_name_1.BuiltInProcName.ForLoop) || origin.includes(built_in_proc_name_1.BuiltInProcName.WhileLoop) || origin.includes(built_in_proc_name_1.BuiltInProcName.RepeatLoop);
|
|
297
297
|
}
|
|
298
298
|
/**
|
|
299
299
|
* Checks whether a control flow graph vertex should be skipped during visitation.
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.mapDataFrameReplacementFunction = mapDataFrameReplacementFunction;
|
|
4
4
|
const config_1 = require("../../../config");
|
|
5
|
-
const built_in_1 = require("../../../dataflow/environments/built-in");
|
|
6
5
|
const vertex_1 = require("../../../dataflow/graph/vertex");
|
|
7
6
|
const make_argument_1 = require("../../../dataflow/internal/process/functions/call/argument/make-argument");
|
|
8
7
|
const r_function_call_1 = require("../../../r-bridge/lang-4.x/ast/model/nodes/r-function-call");
|
|
@@ -12,6 +11,7 @@ const semantics_1 = require("../semantics");
|
|
|
12
11
|
const access_mapper_1 = require("./access-mapper");
|
|
13
12
|
const arguments_1 = require("./arguments");
|
|
14
13
|
const identifier_1 = require("../../../dataflow/environments/identifier");
|
|
14
|
+
const built_in_proc_name_1 = require("../../../dataflow/environments/built-in-proc-name");
|
|
15
15
|
/** Mapper for mapping the supported data frame replacement functions to mapper functions */
|
|
16
16
|
const DataFrameReplacementFunctionMapper = {
|
|
17
17
|
'colnames': mapDataFrameColNamesAssignment,
|
|
@@ -59,7 +59,7 @@ function isDataFrameReplacement(functionName) {
|
|
|
59
59
|
}
|
|
60
60
|
function hasParentReplacement(node, dfg) {
|
|
61
61
|
const parentVertex = node.info.parent ? dfg.getVertex(node.info.parent) : undefined;
|
|
62
|
-
return (0, vertex_1.isFunctionCallVertex)(parentVertex) && parentVertex.origin.includes(
|
|
62
|
+
return (0, vertex_1.isFunctionCallVertex)(parentVertex) && parentVertex.origin.includes(built_in_proc_name_1.BuiltInProcName.Replacement);
|
|
63
63
|
}
|
|
64
64
|
function mapDataFrameContentAssignment(access, expression, inference) {
|
|
65
65
|
const dataFrame = access.accessed;
|
package/benchmark/slicer.d.ts
CHANGED
|
@@ -8,12 +8,12 @@ import type { SliceResult } from '../slicing/static/slicer-types';
|
|
|
8
8
|
import type { ReconstructionResult } from '../reconstruct/reconstruct';
|
|
9
9
|
import type { PerSliceStats, SlicerStats, SlicerStatsDfShape } from './stats/stats';
|
|
10
10
|
import type { NormalizedAst } from '../r-bridge/lang-4.x/ast/model/processing/decorate';
|
|
11
|
-
import
|
|
11
|
+
import { SlicingCriteria } from '../slicing/criterion/parse';
|
|
12
12
|
import { type RParseRequestFromFile, type RParseRequestFromText } from '../r-bridge/retriever';
|
|
13
13
|
import { type SlicingCriteriaFilter } from '../slicing/criterion/collect-all';
|
|
14
14
|
import type { AutoSelectPredicate } from '../reconstruct/auto-select/auto-select-defaults';
|
|
15
15
|
import type { KnownParserName } from '../r-bridge/parser';
|
|
16
|
-
import {
|
|
16
|
+
import { FlowrConfig } from '../config';
|
|
17
17
|
/**
|
|
18
18
|
* The logger to be used for benchmarking as a global object.
|
|
19
19
|
*/
|
|
@@ -63,6 +63,7 @@ export declare class BenchmarkSlicer {
|
|
|
63
63
|
private dataflow;
|
|
64
64
|
private normalizedAst;
|
|
65
65
|
private controlFlow;
|
|
66
|
+
private callGraph;
|
|
66
67
|
private totalStopwatch;
|
|
67
68
|
private finished;
|
|
68
69
|
private executor;
|
|
@@ -72,7 +73,7 @@ export declare class BenchmarkSlicer {
|
|
|
72
73
|
* Initialize the slicer on the given request.
|
|
73
74
|
* Can only be called once for each instance.
|
|
74
75
|
*/
|
|
75
|
-
init(request: RParseRequestFromFile | RParseRequestFromText, config:
|
|
76
|
+
init(request: RParseRequestFromFile | RParseRequestFromText, config: FlowrConfig, autoSelectIf?: AutoSelectPredicate, threshold?: number): Promise<void>;
|
|
76
77
|
private calculateStatsAfterInit;
|
|
77
78
|
/**
|
|
78
79
|
* Slice for the given {@link SlicingCriteria}.
|
|
@@ -84,6 +85,7 @@ export declare class BenchmarkSlicer {
|
|
|
84
85
|
* Extract the control flow graph using {@link extractCFG}
|
|
85
86
|
*/
|
|
86
87
|
extractCFG(): void;
|
|
88
|
+
extractCG(): void;
|
|
87
89
|
/**
|
|
88
90
|
* Infer the shape of data frames using abstract interpretation with {@link inferDataFrameShapes}
|
|
89
91
|
* @returns The statistics of the data frame shape inference
|
package/benchmark/slicer.js
CHANGED
|
@@ -13,6 +13,7 @@ const seedrandom_1 = __importDefault(require("seedrandom"));
|
|
|
13
13
|
const log_1 = require("../util/log");
|
|
14
14
|
const assert_1 = require("../util/assert");
|
|
15
15
|
const strings_1 = require("../util/text/strings");
|
|
16
|
+
const parse_1 = require("../slicing/criterion/parse");
|
|
16
17
|
const default_pipelines_1 = require("../core/steps/pipeline/default-pipelines");
|
|
17
18
|
const retriever_1 = require("../r-bridge/retriever");
|
|
18
19
|
const collect_all_1 = require("../slicing/criterion/collect-all");
|
|
@@ -31,6 +32,7 @@ const fs_1 = __importDefault(require("fs"));
|
|
|
31
32
|
const flowr_analyzer_context_1 = require("../project/context/flowr-analyzer-context");
|
|
32
33
|
const r_project_1 = require("../r-bridge/lang-4.x/ast/model/nodes/r-project");
|
|
33
34
|
const r_comment_1 = require("../r-bridge/lang-4.x/ast/model/nodes/r-comment");
|
|
35
|
+
const call_graph_1 = require("../dataflow/graph/call-graph");
|
|
34
36
|
/**
|
|
35
37
|
* The logger to be used for benchmarking as a global object.
|
|
36
38
|
*/
|
|
@@ -47,6 +49,7 @@ class BenchmarkSlicer {
|
|
|
47
49
|
dataflow;
|
|
48
50
|
normalizedAst;
|
|
49
51
|
controlFlow;
|
|
52
|
+
callGraph;
|
|
50
53
|
totalStopwatch;
|
|
51
54
|
finished = false;
|
|
52
55
|
// Yes, this is unclean, but we know that we assign the executor during the initialization and this saves us from having to check for nullability every time
|
|
@@ -65,10 +68,10 @@ class BenchmarkSlicer {
|
|
|
65
68
|
// we know these are in sync so we just cast to one of them
|
|
66
69
|
this.parser = await this.commonMeasurements.measure('initialize R session', async () => {
|
|
67
70
|
if (this.parserName === 'r-shell') {
|
|
68
|
-
return new shell_1.RShell(
|
|
71
|
+
return new shell_1.RShell(config_1.FlowrConfig.getForEngine(config, 'r-shell'));
|
|
69
72
|
}
|
|
70
73
|
else {
|
|
71
|
-
await tree_sitter_executor_1.TreeSitterExecutor.initTreeSitter(
|
|
74
|
+
await tree_sitter_executor_1.TreeSitterExecutor.initTreeSitter(config_1.FlowrConfig.getForEngine(config, 'tree-sitter'));
|
|
72
75
|
return new tree_sitter_executor_1.TreeSitterExecutor();
|
|
73
76
|
}
|
|
74
77
|
});
|
|
@@ -197,15 +200,16 @@ class BenchmarkSlicer {
|
|
|
197
200
|
this.executor.updateRequest({ criterion: slicingCriteria });
|
|
198
201
|
const totalStopwatch = measurements.start('total');
|
|
199
202
|
const slicedOutput = await this.measureSliceStep('slice', measurements, 'static slicing');
|
|
200
|
-
|
|
203
|
+
const decodedCriteria = parse_1.SlicingCriteria.decodeAll(slicingCriteria, this.normalizedAst.idMap);
|
|
204
|
+
stats.slicingCriteria = Array.from(decodedCriteria);
|
|
201
205
|
stats.reconstructedCode = await this.measureSliceStep('reconstruct', measurements, 'reconstruct code');
|
|
202
206
|
totalStopwatch.stop();
|
|
203
207
|
exports.benchmarkLogger.debug(`Produced code for ${JSON.stringify(slicingCriteria)}: ${stats.reconstructedCode.code}`);
|
|
204
208
|
const results = this.executor.getResults(false);
|
|
205
209
|
if (exports.benchmarkLogger.settings.minLevel >= 3 /* LogLevel.Info */) {
|
|
206
|
-
exports.benchmarkLogger.info(`mapped slicing criteria: ${slicedOutput.
|
|
207
|
-
const node = results.normalize.idMap.get(
|
|
208
|
-
return `\n- id: ${
|
|
210
|
+
exports.benchmarkLogger.info(`mapped slicing criteria: ${slicedOutput.slicedFor.map(id => {
|
|
211
|
+
const node = results.normalize.idMap.get(id);
|
|
212
|
+
return `\n- id: ${id}, location: ${JSON.stringify(node?.location)}, lexeme: ${JSON.stringify(node?.lexeme)}`;
|
|
209
213
|
}).join('')}`);
|
|
210
214
|
}
|
|
211
215
|
// if it is not in the dataflow graph it was kept to be safe and should not count to the included nodes
|
|
@@ -228,6 +232,13 @@ class BenchmarkSlicer {
|
|
|
228
232
|
const ast = this.normalizedAst;
|
|
229
233
|
this.controlFlow = this.measureSimpleStep('extract control flow graph', () => (0, extract_cfg_1.extractCfg)(ast, this.context, undefined, undefined, true));
|
|
230
234
|
}
|
|
235
|
+
extractCG() {
|
|
236
|
+
exports.benchmarkLogger.trace('try to extract the call graph');
|
|
237
|
+
this.guardActive();
|
|
238
|
+
const g = this.dataflow?.graph;
|
|
239
|
+
(0, assert_1.guard)(g !== undefined, 'dataflow should be defined for call graph extraction');
|
|
240
|
+
this.callGraph = this.measureSimpleStep('extract call graph', () => call_graph_1.CallGraph.compute(g));
|
|
241
|
+
}
|
|
231
242
|
/**
|
|
232
243
|
* Infer the shape of data frames using abstract interpretation with {@link inferDataFrameShapes}
|
|
233
244
|
* @returns The statistics of the data frame shape inference
|
|
@@ -422,6 +433,7 @@ class BenchmarkSlicer {
|
|
|
422
433
|
const normalizeTime = Number(this.stats.commonMeasurements.get('normalize R AST'));
|
|
423
434
|
const dataflowTime = Number(this.stats.commonMeasurements.get('produce dataflow information'));
|
|
424
435
|
const controlFlowTime = Number(this.stats.commonMeasurements.get('extract control flow graph'));
|
|
436
|
+
const callGraphTime = Number(this.stats.commonMeasurements.get('extract call graph'));
|
|
425
437
|
const dataFrameShapeTime = Number(this.stats.commonMeasurements.get('infer data frame shapes'));
|
|
426
438
|
this.stats.retrieveTimePerToken = {
|
|
427
439
|
raw: retrieveTime / this.stats.input.numberOfRTokens,
|
|
@@ -439,14 +451,18 @@ class BenchmarkSlicer {
|
|
|
439
451
|
raw: (retrieveTime + normalizeTime + dataflowTime) / this.stats.input.numberOfRTokens,
|
|
440
452
|
normalized: (retrieveTime + normalizeTime + dataflowTime) / this.stats.input.numberOfNormalizedTokens
|
|
441
453
|
};
|
|
442
|
-
this.stats.controlFlowTimePerToken =
|
|
454
|
+
this.stats.controlFlowTimePerToken = Number.isNaN(controlFlowTime) ? undefined : {
|
|
443
455
|
raw: controlFlowTime / this.stats.input.numberOfRTokens,
|
|
444
456
|
normalized: controlFlowTime / this.stats.input.numberOfNormalizedTokens,
|
|
445
|
-
}
|
|
446
|
-
this.stats.
|
|
457
|
+
};
|
|
458
|
+
this.stats.callGraphTimePerToken = Number.isNaN(callGraphTime) ? undefined : {
|
|
459
|
+
raw: callGraphTime / this.stats.input.numberOfRTokens,
|
|
460
|
+
normalized: callGraphTime / this.stats.input.numberOfNormalizedTokens,
|
|
461
|
+
};
|
|
462
|
+
this.stats.dataFrameShapeTimePerToken = Number.isNaN(dataFrameShapeTime) ? undefined : {
|
|
447
463
|
raw: dataFrameShapeTime / this.stats.input.numberOfRTokens,
|
|
448
464
|
normalized: dataFrameShapeTime / this.stats.input.numberOfNormalizedTokens,
|
|
449
|
-
}
|
|
465
|
+
};
|
|
450
466
|
return {
|
|
451
467
|
stats: this.stats,
|
|
452
468
|
parse: typeof this.loadedXml === 'string' ? this.loadedXml : JSON.stringify(this.loadedXml),
|
package/benchmark/stats/print.js
CHANGED
|
@@ -104,6 +104,12 @@ Total common time per R token: ${formatNanoseconds(stats.totalCommonTimeP
|
|
|
104
104
|
Control flow extraction: ${print(stats.commonMeasurements, 'extract control flow graph')}
|
|
105
105
|
Control flow extraction per token: ${formatNanoseconds(stats.controlFlowTimePerToken.normalized)}
|
|
106
106
|
Control flow extraction per R token: ${formatNanoseconds(stats.controlFlowTimePerToken.raw)}`;
|
|
107
|
+
}
|
|
108
|
+
if (stats.commonMeasurements.has('extract call graph') && stats.callGraphTimePerToken !== undefined) {
|
|
109
|
+
result += `
|
|
110
|
+
Call graph extraction: ${print(stats.commonMeasurements, 'extract call graph')}
|
|
111
|
+
Call graph extraction per token: ${formatNanoseconds(stats.callGraphTimePerToken.normalized)}
|
|
112
|
+
Call graph extraction per R token: ${formatNanoseconds(stats.callGraphTimePerToken.raw)}`;
|
|
107
113
|
}
|
|
108
114
|
if (stats.commonMeasurements.has('infer data frame shapes') && stats.dataFrameShapeTimePerToken !== undefined) {
|
|
109
115
|
result += `
|
|
@@ -210,6 +216,12 @@ Total common time per R token: ${formatSummarizedTimeMeasure(stats.totalC
|
|
|
210
216
|
Control flow extraction: ${formatSummarizedTimeMeasure(stats.commonMeasurements.get('extract control flow graph'))}
|
|
211
217
|
Control flow extraction per token: ${formatSummarizedTimeMeasure(stats.controlFlowTimePerToken.normalized)}
|
|
212
218
|
Control flow extraction per R token: ${formatSummarizedTimeMeasure(stats.controlFlowTimePerToken.raw)}`;
|
|
219
|
+
}
|
|
220
|
+
if (stats.commonMeasurements.has('extract call graph') && stats.callGraphTimePerToken !== undefined) {
|
|
221
|
+
result += `
|
|
222
|
+
Call graph extraction: ${formatSummarizedTimeMeasure(stats.commonMeasurements.get('extract call graph'))}
|
|
223
|
+
Call graph extraction per token: ${formatSummarizedTimeMeasure(stats.callGraphTimePerToken.normalized)}
|
|
224
|
+
Call graph extraction per R token: ${formatSummarizedTimeMeasure(stats.callGraphTimePerToken.raw)}`;
|
|
213
225
|
}
|
|
214
226
|
if (stats.commonMeasurements.has('infer data frame shapes') && stats.dataFrameShapeTimePerToken !== undefined) {
|
|
215
227
|
result += `
|
|
@@ -6,8 +6,8 @@ import type { TimePerToken } from '../summarizer/data';
|
|
|
6
6
|
import type { MergeableRecord } from '../../util/objects';
|
|
7
7
|
import type { DataFrameOperationName } from '../../abstract-interpretation/data-frame/semantics';
|
|
8
8
|
export declare const RequiredSlicerMeasurements: readonly ["initialize R session", "retrieve AST from R code", "normalize R AST", "produce dataflow information", "close R session", "total"];
|
|
9
|
-
export declare const OptionalSlicerMeasurements: readonly ["extract control flow graph", "infer data frame shapes"];
|
|
10
|
-
export declare const CommonSlicerMeasurements: readonly ["initialize R session", "retrieve AST from R code", "normalize R AST", "produce dataflow information", "close R session", "total", "extract control flow graph", "infer data frame shapes"];
|
|
9
|
+
export declare const OptionalSlicerMeasurements: readonly ["extract control flow graph", "infer data frame shapes", "extract call graph"];
|
|
10
|
+
export declare const CommonSlicerMeasurements: readonly ["initialize R session", "retrieve AST from R code", "normalize R AST", "produce dataflow information", "close R session", "total", "extract control flow graph", "infer data frame shapes", "extract call graph"];
|
|
11
11
|
export type CommonSlicerMeasurements = typeof CommonSlicerMeasurements[number];
|
|
12
12
|
export declare const PerSliceMeasurements: readonly ["static slicing", "reconstruct code", "total"];
|
|
13
13
|
export type PerSliceMeasurements = typeof PerSliceMeasurements[number];
|
|
@@ -91,5 +91,6 @@ export interface SlicerStats {
|
|
|
91
91
|
dataflowTimePerToken: TimePerToken<number>;
|
|
92
92
|
totalCommonTimePerToken: TimePerToken<number>;
|
|
93
93
|
controlFlowTimePerToken?: TimePerToken<number>;
|
|
94
|
+
callGraphTimePerToken?: TimePerToken<number>;
|
|
94
95
|
dataFrameShapeTimePerToken?: TimePerToken<number>;
|
|
95
96
|
}
|
package/benchmark/stats/stats.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.PerSliceMeasurements = exports.CommonSlicerMeasurements = exports.OptionalSlicerMeasurements = exports.RequiredSlicerMeasurements = void 0;
|
|
4
4
|
exports.RequiredSlicerMeasurements = ['initialize R session', 'retrieve AST from R code', 'normalize R AST', 'produce dataflow information', 'close R session', 'total'];
|
|
5
|
-
exports.OptionalSlicerMeasurements = ['extract control flow graph', 'infer data frame shapes'];
|
|
5
|
+
exports.OptionalSlicerMeasurements = ['extract control flow graph', 'infer data frame shapes', 'extract call graph'];
|
|
6
6
|
exports.CommonSlicerMeasurements = [...exports.RequiredSlicerMeasurements, ...exports.OptionalSlicerMeasurements];
|
|
7
7
|
exports.PerSliceMeasurements = ['static slicing', 'reconstruct code', 'total'];
|
|
8
8
|
//# sourceMappingURL=stats.js.map
|
|
@@ -65,6 +65,7 @@ export interface UltimateSlicerStats {
|
|
|
65
65
|
dataflowTimePerToken: TimePerToken;
|
|
66
66
|
totalCommonTimePerToken: TimePerToken;
|
|
67
67
|
controlFlowTimePerToken?: TimePerToken;
|
|
68
|
+
callGraphTimePerToken?: TimePerToken;
|
|
68
69
|
dataFrameShapeTimePerToken?: TimePerToken;
|
|
69
70
|
sliceTimePerToken: TimePerToken;
|
|
70
71
|
reconstructTimePerToken: TimePerToken;
|
|
@@ -25,6 +25,7 @@ function summarizeAllSummarizedStats(stats) {
|
|
|
25
25
|
const dataflowTimesPerToken = [];
|
|
26
26
|
const totalCommonTimesPerToken = [];
|
|
27
27
|
const controlFlowTimePerToken = [];
|
|
28
|
+
const callGraphTimePerToken = [];
|
|
28
29
|
const dataFrameShapeTimePerToken = [];
|
|
29
30
|
const memory = new defaultmap_1.DefaultMap(() => []);
|
|
30
31
|
const reductions = [];
|
|
@@ -52,6 +53,9 @@ function summarizeAllSummarizedStats(stats) {
|
|
|
52
53
|
if (stat.controlFlowTimePerToken !== undefined) {
|
|
53
54
|
controlFlowTimePerToken.push(stat.controlFlowTimePerToken);
|
|
54
55
|
}
|
|
56
|
+
if (stat.callGraphTimePerToken !== undefined) {
|
|
57
|
+
callGraphTimePerToken.push(stat.callGraphTimePerToken);
|
|
58
|
+
}
|
|
55
59
|
if (stat.dataFrameShapeTimePerToken !== undefined) {
|
|
56
60
|
dataFrameShapeTimePerToken.push(stat.dataFrameShapeTimePerToken);
|
|
57
61
|
}
|
|
@@ -82,6 +86,7 @@ function summarizeAllSummarizedStats(stats) {
|
|
|
82
86
|
dataflowTimePerToken: (0, process_1.summarizeTimePerToken)(dataflowTimesPerToken),
|
|
83
87
|
totalCommonTimePerToken: (0, process_1.summarizeTimePerToken)(totalCommonTimesPerToken),
|
|
84
88
|
controlFlowTimePerToken: controlFlowTimePerToken.length > 0 ? (0, process_1.summarizeTimePerToken)(controlFlowTimePerToken) : undefined,
|
|
89
|
+
callGraphTimePerToken: callGraphTimePerToken.length > 0 ? (0, process_1.summarizeTimePerToken)(callGraphTimePerToken) : undefined,
|
|
85
90
|
dataFrameShapeTimePerToken: dataFrameShapeTimePerToken.length > 0 ? (0, process_1.summarizeTimePerToken)(dataFrameShapeTimePerToken) : undefined,
|
|
86
91
|
failedToRepParse,
|
|
87
92
|
timesHitThreshold,
|
package/cli/benchmark-app.d.ts
CHANGED
package/cli/benchmark-app.js
CHANGED
|
@@ -75,6 +75,7 @@ async function benchmark() {
|
|
|
75
75
|
'--sampling-strategy', options['sampling-strategy'],
|
|
76
76
|
...(options.seed ? ['--seed', options.seed] : []),
|
|
77
77
|
...(options.cfg ? ['--cfg'] : []),
|
|
78
|
+
...(options.cg ? ['--cg'] : [])
|
|
78
79
|
]);
|
|
79
80
|
const runs = options.runs ?? 1;
|
|
80
81
|
for (let i = 1; i <= runs; i++) {
|
|
@@ -10,7 +10,8 @@ export interface SingleBenchmarkCliOptions {
|
|
|
10
10
|
parser: KnownParserName;
|
|
11
11
|
'dataframe-shape-inference': boolean;
|
|
12
12
|
'max-slices': number;
|
|
13
|
-
|
|
13
|
+
cfg: boolean;
|
|
14
|
+
cg: boolean;
|
|
14
15
|
threshold?: number;
|
|
15
16
|
'sampling-strategy': string;
|
|
16
17
|
seed?: string;
|