@eagleoutice/flowr 2.2.15 → 2.2.16

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.
Files changed (212) hide show
  1. package/README.md +210 -6
  2. package/benchmark/slicer.d.ts +3 -1
  3. package/benchmark/slicer.js +8 -5
  4. package/benchmark/summarizer/first-phase/process.d.ts +2 -1
  5. package/benchmark/summarizer/first-phase/process.js +2 -2
  6. package/cli/benchmark-app.d.ts +1 -0
  7. package/cli/benchmark-app.js +4 -1
  8. package/cli/benchmark-helper-app.d.ts +1 -0
  9. package/cli/benchmark-helper-app.js +7 -8
  10. package/cli/common/options.js +2 -0
  11. package/cli/export-quads-app.js +2 -1
  12. package/cli/flowr.js +58 -57
  13. package/cli/repl/commands/repl-cfg.js +13 -13
  14. package/cli/repl/commands/repl-commands.js +2 -2
  15. package/cli/repl/commands/repl-dataflow.js +10 -10
  16. package/cli/repl/commands/repl-execute.d.ts +2 -3
  17. package/cli/repl/commands/repl-execute.js +4 -4
  18. package/cli/repl/commands/repl-lineage.js +4 -4
  19. package/cli/repl/commands/repl-main.d.ts +12 -1
  20. package/cli/repl/commands/repl-normalize.js +6 -6
  21. package/cli/repl/commands/repl-parse.js +2 -2
  22. package/cli/repl/commands/repl-query.js +9 -9
  23. package/cli/repl/commands/repl-version.js +1 -1
  24. package/cli/repl/core.d.ts +5 -2
  25. package/cli/repl/core.js +10 -8
  26. package/cli/repl/server/connection.d.ts +3 -1
  27. package/cli/repl/server/connection.js +7 -5
  28. package/cli/repl/server/server.d.ts +3 -2
  29. package/cli/repl/server/server.js +4 -2
  30. package/cli/script-core/statistics-core.d.ts +2 -1
  31. package/cli/script-core/statistics-core.js +2 -2
  32. package/cli/script-core/statistics-helper-core.d.ts +2 -1
  33. package/cli/script-core/statistics-helper-core.js +5 -4
  34. package/cli/slicer-app.js +4 -2
  35. package/cli/statistics-app.js +2 -1
  36. package/cli/statistics-helper-app.js +2 -1
  37. package/config.d.ts +12 -10
  38. package/config.js +26 -42
  39. package/control-flow/cfg-dead-code.js +45 -2
  40. package/control-flow/cfg-simplification.d.ts +2 -0
  41. package/control-flow/control-flow-graph.d.ts +1 -0
  42. package/control-flow/control-flow-graph.js +4 -0
  43. package/control-flow/dfg-cfg-guided-visitor.d.ts +5 -3
  44. package/control-flow/dfg-cfg-guided-visitor.js +15 -4
  45. package/control-flow/extract-cfg.d.ts +4 -2
  46. package/control-flow/extract-cfg.js +4 -3
  47. package/control-flow/semantic-cfg-guided-visitor.d.ts +19 -1
  48. package/control-flow/semantic-cfg-guided-visitor.js +23 -3
  49. package/core/pipeline-executor.d.ts +4 -1
  50. package/core/pipeline-executor.js +6 -5
  51. package/core/steps/all/core/10-normalize.d.ts +2 -0
  52. package/core/steps/all/core/10-normalize.js +1 -1
  53. package/core/steps/all/core/11-normalize-tree-sitter.d.ts +2 -1
  54. package/core/steps/all/core/11-normalize-tree-sitter.js +2 -2
  55. package/core/steps/all/core/20-dataflow.d.ts +2 -1
  56. package/core/steps/all/core/20-dataflow.js +2 -2
  57. package/core/steps/all/static-slicing/00-slice.d.ts +2 -1
  58. package/core/steps/all/static-slicing/00-slice.js +2 -2
  59. package/core/steps/pipeline/default-pipelines.d.ts +32 -31
  60. package/core/steps/pipeline/default-pipelines.js +8 -8
  61. package/core/steps/pipeline-step.d.ts +2 -1
  62. package/dataflow/environments/built-in-config.d.ts +3 -3
  63. package/dataflow/environments/built-in.d.ts +7 -1
  64. package/dataflow/environments/built-in.js +2 -2
  65. package/dataflow/environments/default-builtin-config.js +4 -2
  66. package/dataflow/environments/define.d.ts +2 -1
  67. package/dataflow/environments/define.js +4 -5
  68. package/dataflow/environments/remove.d.ts +6 -0
  69. package/dataflow/environments/remove.js +29 -0
  70. package/dataflow/eval/resolve/alias-tracking.d.ts +7 -2
  71. package/dataflow/eval/resolve/alias-tracking.js +9 -6
  72. package/dataflow/eval/resolve/resolve-argument.d.ts +8 -0
  73. package/dataflow/eval/resolve/resolve-argument.js +118 -0
  74. package/dataflow/eval/resolve/resolve.d.ts +18 -15
  75. package/dataflow/eval/resolve/resolve.js +20 -18
  76. package/dataflow/eval/values/string/string-constants.d.ts +1 -1
  77. package/dataflow/eval/values/string/string-constants.js +7 -2
  78. package/dataflow/extractor.d.ts +2 -1
  79. package/dataflow/extractor.js +2 -1
  80. package/dataflow/internal/process/functions/call/built-in/built-in-access.js +5 -6
  81. package/dataflow/internal/process/functions/call/built-in/built-in-apply.js +1 -1
  82. package/dataflow/internal/process/functions/call/built-in/built-in-assignment.d.ts +4 -2
  83. package/dataflow/internal/process/functions/call/built-in/built-in-assignment.js +11 -11
  84. package/dataflow/internal/process/functions/call/built-in/built-in-eval.js +10 -11
  85. package/dataflow/internal/process/functions/call/built-in/built-in-expression-list.js +7 -2
  86. package/dataflow/internal/process/functions/call/built-in/built-in-for-loop.js +2 -3
  87. package/dataflow/internal/process/functions/call/built-in/built-in-if-then-else.js +1 -1
  88. package/dataflow/internal/process/functions/call/built-in/built-in-list.js +2 -2
  89. package/dataflow/internal/process/functions/call/built-in/built-in-replacement.js +2 -3
  90. package/dataflow/internal/process/functions/call/built-in/built-in-source.d.ts +5 -3
  91. package/dataflow/internal/process/functions/call/built-in/built-in-source.js +15 -15
  92. package/dataflow/internal/process/functions/call/built-in/built-in-vector.js +2 -2
  93. package/dataflow/internal/process/functions/call/built-in/built-in-while-loop.js +1 -1
  94. package/dataflow/internal/process/functions/call/common.js +1 -1
  95. package/dataflow/internal/process/functions/process-parameter.js +1 -1
  96. package/dataflow/origin/dfg-get-symbol-refs.d.ts +21 -0
  97. package/dataflow/origin/dfg-get-symbol-refs.js +50 -0
  98. package/dataflow/processor.d.ts +5 -0
  99. package/documentation/doc-util/doc-cfg.js +4 -3
  100. package/documentation/doc-util/doc-code.d.ts +1 -1
  101. package/documentation/doc-util/doc-dfg.js +3 -2
  102. package/documentation/doc-util/doc-functions.d.ts +24 -0
  103. package/documentation/doc-util/doc-functions.js +65 -0
  104. package/documentation/doc-util/doc-normalized-ast.js +3 -2
  105. package/documentation/doc-util/doc-print.d.ts +5 -0
  106. package/documentation/doc-util/doc-print.js +36 -0
  107. package/documentation/doc-util/doc-query.js +3 -2
  108. package/documentation/doc-util/doc-repl.js +2 -1
  109. package/documentation/doc-util/doc-search.js +3 -2
  110. package/documentation/doc-util/doc-types.d.ts +28 -6
  111. package/documentation/doc-util/doc-types.js +89 -45
  112. package/documentation/print-cfg-wiki.js +6 -7
  113. package/documentation/print-core-wiki.js +5 -5
  114. package/documentation/print-dataflow-graph-wiki.js +10 -10
  115. package/documentation/print-engines-wiki.js +1 -2
  116. package/documentation/print-faq-wiki.js +8 -2
  117. package/documentation/print-interface-wiki.js +1 -2
  118. package/documentation/print-linter-issue.d.ts +1 -0
  119. package/documentation/print-linter-issue.js +71 -0
  120. package/documentation/print-linter-wiki.js +219 -34
  121. package/documentation/print-linting-and-testing-wiki.js +2 -4
  122. package/documentation/print-normalized-ast-wiki.js +3 -3
  123. package/documentation/print-query-wiki.js +1 -2
  124. package/documentation/print-readme.js +24 -1
  125. package/documentation/print-search-wiki.js +1 -2
  126. package/linter/linter-executor.d.ts +3 -1
  127. package/linter/linter-executor.js +3 -2
  128. package/linter/linter-format.d.ts +67 -7
  129. package/linter/linter-format.js +12 -1
  130. package/linter/linter-rules.d.ts +155 -16
  131. package/linter/linter-rules.js +12 -4
  132. package/linter/linter-tags.d.ts +80 -0
  133. package/linter/linter-tags.js +85 -0
  134. package/linter/rules/absolute-path.d.ts +71 -0
  135. package/linter/rules/absolute-path.js +177 -0
  136. package/linter/rules/deprecated-functions.d.ts +43 -0
  137. package/linter/rules/deprecated-functions.js +58 -0
  138. package/linter/rules/{2-file-path-validity.d.ts → file-path-validity.d.ts} +16 -6
  139. package/linter/rules/{2-file-path-validity.js → file-path-validity.js} +21 -13
  140. package/linter/rules/naming-convention.d.ts +71 -0
  141. package/linter/rules/naming-convention.js +164 -0
  142. package/linter/rules/seeded-randomness.d.ts +65 -0
  143. package/linter/rules/seeded-randomness.js +122 -0
  144. package/linter/rules/unused-definition.d.ts +41 -0
  145. package/linter/rules/unused-definition.js +105 -0
  146. package/package.json +4 -1
  147. package/queries/base-query-format.d.ts +2 -0
  148. package/queries/catalog/call-context-query/call-context-query-executor.d.ts +1 -1
  149. package/queries/catalog/call-context-query/call-context-query-executor.js +2 -2
  150. package/queries/catalog/cluster-query/cluster-query-format.d.ts +1 -1
  151. package/queries/catalog/config-query/config-query-executor.d.ts +1 -1
  152. package/queries/catalog/config-query/config-query-executor.js +2 -3
  153. package/queries/catalog/control-flow-query/control-flow-query-executor.d.ts +1 -1
  154. package/queries/catalog/control-flow-query/control-flow-query-executor.js +2 -2
  155. package/queries/catalog/control-flow-query/control-flow-query-format.d.ts +1 -1
  156. package/queries/catalog/dataflow-lens-query/dataflow-lens-query-format.d.ts +1 -1
  157. package/queries/catalog/dataflow-query/dataflow-query-format.d.ts +1 -1
  158. package/queries/catalog/dependencies-query/dependencies-query-executor.js +4 -116
  159. package/queries/catalog/dependencies-query/dependencies-query-format.d.ts +1 -1
  160. package/queries/catalog/happens-before-query/happens-before-query-format.d.ts +1 -1
  161. package/queries/catalog/id-map-query/id-map-query-format.d.ts +1 -1
  162. package/queries/catalog/lineage-query/lineage-query-format.d.ts +1 -1
  163. package/queries/catalog/linter-query/linter-query-executor.d.ts +1 -1
  164. package/queries/catalog/linter-query/linter-query-executor.js +2 -2
  165. package/queries/catalog/linter-query/linter-query-format.d.ts +1 -1
  166. package/queries/catalog/linter-query/linter-query-format.js +16 -12
  167. package/queries/catalog/normalized-ast-query/normalized-ast-query-format.d.ts +1 -1
  168. package/queries/catalog/origin-query/origin-query-format.d.ts +1 -1
  169. package/queries/catalog/project-query/project-query-format.d.ts +1 -1
  170. package/queries/catalog/resolve-value-query/resolve-value-query-executor.d.ts +1 -1
  171. package/queries/catalog/resolve-value-query/resolve-value-query-executor.js +2 -2
  172. package/queries/catalog/resolve-value-query/resolve-value-query-format.d.ts +1 -1
  173. package/queries/catalog/search-query/search-query-executor.d.ts +1 -1
  174. package/queries/catalog/search-query/search-query-executor.js +2 -2
  175. package/queries/catalog/search-query/search-query-format.d.ts +1 -1
  176. package/queries/catalog/static-slice-query/static-slice-query-executor.d.ts +1 -1
  177. package/queries/catalog/static-slice-query/static-slice-query-executor.js +2 -2
  178. package/queries/catalog/static-slice-query/static-slice-query-format.d.ts +1 -1
  179. package/queries/query.d.ts +15 -15
  180. package/r-bridge/lang-4.x/ast/parser/json/parser.d.ts +2 -1
  181. package/r-bridge/lang-4.x/ast/parser/json/parser.js +4 -2
  182. package/r-bridge/lang-4.x/convert-values.js +2 -1
  183. package/r-bridge/lang-4.x/tree-sitter/tree-sitter-executor.d.ts +3 -1
  184. package/r-bridge/lang-4.x/tree-sitter/tree-sitter-executor.js +4 -4
  185. package/r-bridge/lang-4.x/tree-sitter/tree-sitter-normalize.d.ts +1 -1
  186. package/r-bridge/lang-4.x/tree-sitter/tree-sitter-normalize.js +7 -5
  187. package/r-bridge/shell.d.ts +3 -2
  188. package/r-bridge/shell.js +4 -5
  189. package/search/flowr-search-builder.d.ts +6 -2
  190. package/search/flowr-search-builder.js +7 -0
  191. package/search/flowr-search-filters.d.ts +32 -8
  192. package/search/flowr-search-filters.js +42 -15
  193. package/search/flowr-search.d.ts +4 -0
  194. package/search/search-executor/search-enrichers.d.ts +7 -3
  195. package/search/search-executor/search-enrichers.js +29 -20
  196. package/search/search-executor/search-generators.js +1 -1
  197. package/search/search-executor/search-transformer.d.ts +2 -0
  198. package/search/search-executor/search-transformer.js +10 -1
  199. package/slicing/static/static-slicer.d.ts +1 -1
  200. package/slicing/static/static-slicer.js +2 -3
  201. package/statistics/statistics.d.ts +3 -1
  202. package/statistics/statistics.js +5 -4
  203. package/util/containers.d.ts +12 -9
  204. package/util/containers.js +12 -9
  205. package/util/objects.d.ts +5 -4
  206. package/util/range.d.ts +5 -1
  207. package/util/range.js +11 -3
  208. package/util/text/strings.d.ts +6 -0
  209. package/util/text/strings.js +35 -0
  210. package/util/version.js +1 -1
  211. package/linter/rules/1-deprecated-functions.d.ts +0 -34
  212. package/linter/rules/1-deprecated-functions.js +0 -54
package/README.md CHANGED
@@ -12,6 +12,210 @@ available for [VSCode](https://marketplace.visualstudio.com/items?itemName=code-
12
12
  and [Docker](https://hub.docker.com/r/eagleoutice/flowr).
13
13
  It offers a wide variety of features, for example:
14
14
 
15
+ * 🐞 **code linting**\
16
+ Analyze your R scripts for common issues and potential bugs (see the [wiki page](https://github.com/flowr-analysis/flowr/wiki/Linter) for more information on the currently supported linters).
17
+
18
+
19
+ <details><summary style="">Example: Linting code with flowR</summary>
20
+
21
+ To lint your code, you can use the [REPL](https://github.com/flowr-analysis/flowr/wiki/Interface#using-the-repl) or the [Visual Studio Code extension](https://marketplace.visualstudio.com/items?itemName=code-inspect.vscode-flowr) (see [vscode-flowr#283](https://github.com/flowr-analysis/vscode-flowr/pull/283)).
22
+
23
+
24
+
25
+ ```shell
26
+ $ docker run -it --rm eagleoutice/flowr # or npm run flowr
27
+ flowR repl using flowR v2.2.15, R v4.5.0 (r-shell engine)
28
+ R> :query @linter "read.csv(\"/root/x.txt\")"
29
+ ```
30
+
31
+ <details>
32
+ <summary style='color:gray'>Output</summary>
33
+
34
+
35
+ ```text
36
+ Query: linter (2 ms)
37
+ ╰ **Deprecated Functions** (deprecated-functions):
38
+ ╰ _Metadata_: <code>{"totalDeprecatedCalls":0,"totalDeprecatedFunctionDefinitions":0,"searchTimeMs":0,"processTimeMs":0}</code>
39
+ ╰ **File Path Validity** (file-path-validity):
40
+ ╰ definitely:
41
+ ╰ Path `/root/x.txt` at 1.1-23
42
+ ╰ _Metadata_: <code>{"totalReads":1,"totalUnknown":0,"totalWritesBeforeAlways":0,"totalValid":0,"searchTimeMs":1,"processTimeMs":0}</code>
43
+ ╰ **Seeded Randomness** (seeded-randomness):
44
+ ╰ _Metadata_: <code>{"consumerCalls":0,"callsWithFunctionProducers":0,"callsWithAssignmentProducers":0,"callsWithNonConstantProducers":0,"searchTimeMs":0,"processTimeMs":0}</code>
45
+ ╰ **Absolute Paths** (absolute-file-paths):
46
+ ╰ definitely:
47
+ ╰ Path `/root/x.txt` at 1.1-23
48
+ ╰ _Metadata_: <code>{"totalConsidered":1,"totalUnknown":0,"searchTimeMs":1,"processTimeMs":0}</code>
49
+ ╰ **Unused Definitions** (unused-definitions):
50
+ ╰ _Metadata_: <code>{"totalConsidered":0,"searchTimeMs":0,"processTimeMs":0}</code>
51
+ ╰ **Naming Convention** (naming-convention):
52
+ ╰ _Metadata_: <code>{"numMatches":0,"numBreak":0,"searchTimeMs":0,"processTimeMs":0}</code>
53
+ All queries together required ≈2 ms (1ms accuracy, total 7 ms)
54
+ ```
55
+
56
+
57
+
58
+ The linter will analyze the code and return any issues found.
59
+ Formatted more nicely, this returns:
60
+
61
+
62
+
63
+
64
+ ```json
65
+ [ { "type": "linter" } ]
66
+ ```
67
+
68
+
69
+
70
+
71
+ _Results (prettified and summarized):_
72
+
73
+ Query: **linter** (10 ms)\
74
+ &nbsp;&nbsp;&nbsp;╰ **Deprecated Functions** (deprecated-functions):\
75
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;╰ _Metadata_: <code>{"totalDeprecatedCalls":0,"totalDeprecatedFunctionDefinitions":0,"searchTimeMs":2,"processTimeMs":0}</code>\
76
+ &nbsp;&nbsp;&nbsp;╰ **File Path Validity** (file-path-validity):\
77
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;╰ definitely:\
78
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;╰ Path `/root/x.txt` at 1.1-23\
79
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;╰ _Metadata_: <code>{"totalReads":1,"totalUnknown":0,"totalWritesBeforeAlways":0,"totalValid":0,"searchTimeMs":4,"processTimeMs":1}</code>\
80
+ &nbsp;&nbsp;&nbsp;╰ **Seeded Randomness** (seeded-randomness):\
81
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;╰ _Metadata_: <code>{"consumerCalls":0,"callsWithFunctionProducers":0,"callsWithAssignmentProducers":0,"callsWithNonConstantProducers":0,"searchTimeMs":0,"processTimeMs":0}</code>\
82
+ &nbsp;&nbsp;&nbsp;╰ **Absolute Paths** (absolute-file-paths):\
83
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;╰ definitely:\
84
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;╰ Path `/root/x.txt` at 1.1-23\
85
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;╰ _Metadata_: <code>{"totalConsidered":1,"totalUnknown":0,"searchTimeMs":1,"processTimeMs":1}</code>\
86
+ &nbsp;&nbsp;&nbsp;╰ **Unused Definitions** (unused-definitions):\
87
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;╰ _Metadata_: <code>{"totalConsidered":0,"searchTimeMs":0,"processTimeMs":0}</code>\
88
+ &nbsp;&nbsp;&nbsp;╰ **Naming Convention** (naming-convention):\
89
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;╰ _Metadata_: <code>{"numMatches":0,"numBreak":0,"searchTimeMs":0,"processTimeMs":0}</code>\
90
+ _All queries together required ≈10 ms (1ms accuracy, total 208 ms)_
91
+
92
+ <details> <summary style="color:gray">Show Detailed Results as Json</summary>
93
+
94
+ The analysis required _207.6 ms_ (including parsing and normalization and the query) within the generation environment.
95
+
96
+ 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.
97
+ Please consult the [Interface](https://github.com/flowr-analysis/flowr/wiki/Interface) wiki page for more information on how to get those.
98
+
99
+
100
+
101
+
102
+ ```json
103
+ {
104
+ "linter": {
105
+ "results": {
106
+ "deprecated-functions": {
107
+ "results": [],
108
+ ".meta": {
109
+ "totalDeprecatedCalls": 0,
110
+ "totalDeprecatedFunctionDefinitions": 0,
111
+ "searchTimeMs": 2,
112
+ "processTimeMs": 0
113
+ }
114
+ },
115
+ "file-path-validity": {
116
+ "results": [
117
+ {
118
+ "range": [
119
+ 1,
120
+ 1,
121
+ 1,
122
+ 23
123
+ ],
124
+ "filePath": "/root/x.txt",
125
+ "certainty": "definitely"
126
+ }
127
+ ],
128
+ ".meta": {
129
+ "totalReads": 1,
130
+ "totalUnknown": 0,
131
+ "totalWritesBeforeAlways": 0,
132
+ "totalValid": 0,
133
+ "searchTimeMs": 4,
134
+ "processTimeMs": 1
135
+ }
136
+ },
137
+ "seeded-randomness": {
138
+ "results": [],
139
+ ".meta": {
140
+ "consumerCalls": 0,
141
+ "callsWithFunctionProducers": 0,
142
+ "callsWithAssignmentProducers": 0,
143
+ "callsWithNonConstantProducers": 0,
144
+ "searchTimeMs": 0,
145
+ "processTimeMs": 0
146
+ }
147
+ },
148
+ "absolute-file-paths": {
149
+ "results": [
150
+ {
151
+ "certainty": "definitely",
152
+ "filePath": "/root/x.txt",
153
+ "range": [
154
+ 1,
155
+ 1,
156
+ 1,
157
+ 23
158
+ ]
159
+ }
160
+ ],
161
+ ".meta": {
162
+ "totalConsidered": 1,
163
+ "totalUnknown": 0,
164
+ "searchTimeMs": 1,
165
+ "processTimeMs": 1
166
+ }
167
+ },
168
+ "unused-definitions": {
169
+ "results": [],
170
+ ".meta": {
171
+ "totalConsidered": 0,
172
+ "searchTimeMs": 0,
173
+ "processTimeMs": 0
174
+ }
175
+ },
176
+ "naming-convention": {
177
+ "results": [],
178
+ ".meta": {
179
+ "numMatches": 0,
180
+ "numBreak": 0,
181
+ "searchTimeMs": 0,
182
+ "processTimeMs": 0
183
+ }
184
+ }
185
+ },
186
+ ".meta": {
187
+ "timing": 10
188
+ }
189
+ },
190
+ ".meta": {
191
+ "timing": 10
192
+ }
193
+ }
194
+ ```
195
+
196
+
197
+
198
+ </details>
199
+
200
+
201
+
202
+
203
+
204
+
205
+
206
+
207
+
208
+
209
+ </details>
210
+
211
+
212
+
213
+
214
+
215
+ </details>
216
+
217
+
218
+
15
219
  * 🍕 **program slicing**\
16
220
  Given a point of interest like the visualization of a plot, _flowR_ reduces the program to just the parts which are relevant
17
221
  for the computation of the point of interest.
@@ -51,7 +255,7 @@ It offers a wide variety of features, for example:
51
255
 
52
256
  ```shell
53
257
  $ docker run -it --rm eagleoutice/flowr # or npm run flowr
54
- flowR repl using flowR v2.2.14, R v4.4.3 (r-shell engine)
258
+ flowR repl using flowR v2.2.15, R v4.5.0 (r-shell engine)
55
259
  R> :slicer test/testfiles/example.R --criterion "11@sum"
56
260
  ```
57
261
 
@@ -98,7 +302,7 @@ It offers a wide variety of features, for example:
98
302
 
99
303
 
100
304
  * 🚀 **fast data- and control-flow graphs**\
101
- Within just <i><span title="This measurement is automatically fetched from the latest benchmark!">133.8 ms</span></i> (as of May 31, 2025),
305
+ Within just <i><span title="This measurement is automatically fetched from the latest benchmark!">136.2 ms</span></i> (as of Jun 2, 2025),
102
306
  _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,
103
307
  and consult the [wiki pages](https://github.com/flowr-analysis/flowr/wiki/Dataflow-Graph) for more details on the dataflow graph.
104
308
 
@@ -134,7 +338,7 @@ It offers a wide variety of features, for example:
134
338
 
135
339
  ```shell
136
340
  $ docker run -it --rm eagleoutice/flowr # or npm run flowr
137
- flowR repl using flowR v2.2.14, R v4.4.3 (r-shell engine)
341
+ flowR repl using flowR v2.2.15, R v4.5.0 (r-shell engine)
138
342
  R> :dataflow* test/testfiles/example.R
139
343
  ```
140
344
 
@@ -411,7 +615,7 @@ It offers a wide variety of features, for example:
411
615
  linkStyle 68 stroke:gray;
412
616
  35 -->|"CD-True"| 36
413
617
  linkStyle 69 stroke:gray,color:gray;
414
- 36 -->|"reads, argument"| 12
618
+ 36 -->|"argument"| 12
415
619
  36 -->|"reads, argument"| 20
416
620
  36 -->|"argument, non-standard-evaluation"| 35
417
621
  36 -.->|"reads, calls"| built-in:for
@@ -435,7 +639,7 @@ It offers a wide variety of features, for example:
435
639
  ```
436
640
 
437
641
 
438
- (The analysis required _22.8 ms_ (including parse and normalize, using the [r-shell](https://github.com/flowr-analysis/flowr/wiki/Engines) engine) within the generation environment.)
642
+ (The analysis required _13.9 ms_ (including parse and normalize, using the [r-shell](https://github.com/flowr-analysis/flowr/wiki/Engines) engine) within the generation environment.)
439
643
 
440
644
 
441
645
 
@@ -478,7 +682,7 @@ You can enter <span title="Description (Repl Command): Show help information (al
478
682
 
479
683
  <summary>Example REPL session</summary>
480
684
 
481
- ![Example of a simple REPL session](wiki/gif/repl-demo.gif)
685
+ ![Example of a simple REPL session](wiki/gif/repl-demo-opt.gif)
482
686
 
483
687
  </details>
484
688
 
@@ -13,6 +13,7 @@ import type { RParseRequestFromFile, RParseRequestFromText } from '../r-bridge/r
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 type { FlowrConfigOptions } from '../config';
16
17
  /**
17
18
  * The logger to be used for benchmarking as a global object.
18
19
  */
@@ -69,7 +70,7 @@ export declare class BenchmarkSlicer {
69
70
  * Initialize the slicer on the given request.
70
71
  * Can only be called once for each instance.
71
72
  */
72
- init(request: RParseRequestFromFile | RParseRequestFromText, autoSelectIf?: AutoSelectPredicate, threshold?: number): Promise<void>;
73
+ init(request: RParseRequestFromFile | RParseRequestFromText, config: FlowrConfigOptions, autoSelectIf?: AutoSelectPredicate, threshold?: number): Promise<void>;
73
74
  private calculateStatsAfterInit;
74
75
  /**
75
76
  * Counts the number of stored indices in the dataflow graph created by the pointer analysis.
@@ -113,6 +114,7 @@ export declare class BenchmarkSlicer {
113
114
  sampleCount?: number;
114
115
  maxSliceCount?: number;
115
116
  sampleStrategy?: SamplingStrategy;
117
+ seed?: string;
116
118
  }): Promise<number>;
117
119
  /**
118
120
  * Retrieves the final stats and closes the shell session.
@@ -10,6 +10,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
10
10
  exports.BenchmarkSlicer = exports.benchmarkLogger = void 0;
11
11
  const stopwatch_1 = require("./stopwatch");
12
12
  const fs_1 = __importDefault(require("fs"));
13
+ const seedrandom_1 = __importDefault(require("seedrandom"));
13
14
  const log_1 = require("../util/log");
14
15
  const assert_1 = require("../util/assert");
15
16
  const strings_1 = require("../util/text/strings");
@@ -24,6 +25,7 @@ const tree_sitter_types_1 = require("../r-bridge/lang-4.x/tree-sitter/tree-sitte
24
25
  const tree_sitter_executor_1 = require("../r-bridge/lang-4.x/tree-sitter/tree-sitter-executor");
25
26
  const vertex_1 = require("../dataflow/graph/vertex");
26
27
  const arrays_1 = require("../util/collections/arrays");
28
+ const config_1 = require("../config");
27
29
  /**
28
30
  * The logger to be used for benchmarking as a global object.
29
31
  */
@@ -51,15 +53,15 @@ class BenchmarkSlicer {
51
53
  * Initialize the slicer on the given request.
52
54
  * Can only be called once for each instance.
53
55
  */
54
- async init(request, autoSelectIf, threshold) {
56
+ async init(request, config, autoSelectIf, threshold) {
55
57
  (0, assert_1.guard)(this.stats === undefined, 'cannot initialize the slicer twice');
56
58
  // we know these are in sync so we just cast to one of them
57
59
  this.parser = await this.commonMeasurements.measure('initialize R session', async () => {
58
60
  if (this.parserName === 'r-shell') {
59
- return new shell_1.RShell();
61
+ return new shell_1.RShell((0, config_1.getEngineConfig)(config, 'r-shell'));
60
62
  }
61
63
  else {
62
- await tree_sitter_executor_1.TreeSitterExecutor.initTreeSitter();
64
+ await tree_sitter_executor_1.TreeSitterExecutor.initTreeSitter((0, config_1.getEngineConfig)(config, 'tree-sitter'));
63
65
  return new tree_sitter_executor_1.TreeSitterExecutor();
64
66
  }
65
67
  });
@@ -68,7 +70,7 @@ class BenchmarkSlicer {
68
70
  criterion: [],
69
71
  autoSelectIf,
70
72
  threshold,
71
- });
73
+ }, config);
72
74
  this.loadedXml = (await this.measureCommonStep('parse', 'retrieve AST from R code')).parsed;
73
75
  this.normalizedAst = await this.measureCommonStep('normalize', 'normalize R AST');
74
76
  this.dataflow = await this.measureCommonStep('dataflow', 'produce dataflow information');
@@ -301,7 +303,8 @@ class BenchmarkSlicer {
301
303
  allCriteria = (0, arrays_1.equidistantSampling)(allCriteria, sampleCount, 'ceil');
302
304
  }
303
305
  else {
304
- allCriteria.sort(() => Math.random() - 0.5);
306
+ const random = options.seed ? (0, seedrandom_1.default)(options.seed) : Math.random;
307
+ allCriteria.sort(() => random() - 0.5);
305
308
  allCriteria.length = Math.min(allCriteria.length, sampleCount);
306
309
  }
307
310
  }
@@ -2,11 +2,12 @@ import type { Reduction, SummarizedSlicerStats, TimePerToken } from '../data';
2
2
  import type { SummarizedMeasurement } from '../../../util/summarizer';
3
3
  import type { PerSliceStats, SlicerStats } from '../../stats/stats';
4
4
  import type { SlicingCriteria } from '../../../slicing/criterion/parse';
5
+ import type { RShellEngineConfig } from '../../../config';
5
6
  /**
6
7
  * Summarizes the given stats by calculating the min, max, median, mean, and the standard deviation for each measurement.
7
8
  * @see Slicer
8
9
  */
9
- export declare function summarizeSlicerStats(stats: SlicerStats, report?: (criteria: SlicingCriteria, stats: PerSliceStats) => void): Promise<Readonly<SummarizedSlicerStats>>;
10
+ export declare function summarizeSlicerStats(stats: SlicerStats, report?: (criteria: SlicingCriteria, stats: PerSliceStats) => void, engineConf?: RShellEngineConfig): Promise<Readonly<SummarizedSlicerStats>>;
10
11
  export declare function summarizeSummarizedMeasurement(data: SummarizedMeasurement[]): SummarizedMeasurement;
11
12
  export declare function summarizeSummarizedReductions(reductions: Reduction<SummarizedMeasurement>[]): Reduction<SummarizedMeasurement>;
12
13
  export declare function summarizeSummarizedTimePerToken(times: TimePerToken[]): TimePerToken;
@@ -107,10 +107,10 @@ function calculateReductionForSlice(input, dataflow, perSlice, ignoreFluff) {
107
107
  * @see Slicer
108
108
  */
109
109
  async function summarizeSlicerStats(stats, report = () => {
110
- }) {
110
+ }, engineConf) {
111
111
  const collect = new defaultmap_1.DefaultMap(() => []);
112
112
  const sizeOfSliceCriteria = [];
113
- const reParseShellSession = new shell_1.RShell();
113
+ const reParseShellSession = new shell_1.RShell(engineConf);
114
114
  const sliceTimes = [];
115
115
  const reconstructTimes = [];
116
116
  const totalTimes = [];
@@ -8,6 +8,7 @@ export interface BenchmarkCliOptions {
8
8
  parallel: number;
9
9
  limit?: number;
10
10
  runs?: number;
11
+ seed?: string;
11
12
  parser: KnownParserName;
12
13
  'enable-pointer-tracking': boolean;
13
14
  'max-file-slices': number;
@@ -5,6 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const fs_1 = __importDefault(require("fs"));
7
7
  const path_1 = __importDefault(require("path"));
8
+ const seedrandom_1 = __importDefault(require("seedrandom"));
8
9
  const assert_1 = require("../util/assert");
9
10
  const files_1 = require("../util/files");
10
11
  const log_1 = require("../util/log");
@@ -56,8 +57,9 @@ async function benchmark() {
56
57
  }
57
58
  if (options.limit) {
58
59
  log_1.log.info(`limiting to ${options.limit} files`);
60
+ const random = options.seed ? (0, seedrandom_1.default)(options.seed) : Math.random;
59
61
  // shuffle and limit
60
- files.sort(() => Math.random() - 0.5);
62
+ files.sort(() => random() - 0.5);
61
63
  }
62
64
  const limit = options.limit ?? files.length;
63
65
  const verboseAdd = options.verbose ? ['--verbose'] : [];
@@ -71,6 +73,7 @@ async function benchmark() {
71
73
  '--max-slices', `${options['max-file-slices']}`,
72
74
  ...(options.threshold ? ['--threshold', `${options.threshold}`] : []),
73
75
  '--sampling-strategy', options['sampling-strategy'],
76
+ ...(options.seed ? ['--seed', options.seed] : []),
74
77
  ]);
75
78
  const runs = options.runs ?? 1;
76
79
  for (let i = 1; i <= runs; i++) {
@@ -12,4 +12,5 @@ export interface SingleBenchmarkCliOptions {
12
12
  'max-slices': number;
13
13
  threshold?: number;
14
14
  'sampling-strategy': string;
15
+ seed?: string;
15
16
  }
@@ -39,12 +39,11 @@ async function benchmark() {
39
39
  fs_1.default.mkdirSync(directory, { recursive: true });
40
40
  }
41
41
  // Enable pointer analysis if requested, otherwise disable it
42
- if (options['enable-pointer-tracking']) {
43
- (0, config_1.amendConfig)({ solver: { ...(0, config_1.getConfig)().solver, pointerTracking: true, } });
44
- }
45
- else {
46
- (0, config_1.amendConfig)({ solver: { ...(0, config_1.getConfig)().solver, pointerTracking: false, } });
47
- }
42
+ const config = (0, config_1.getConfig)();
43
+ (0, config_1.amendConfig)(config, c => {
44
+ c.solver.pointerTracking = options['enable-pointer-tracking'];
45
+ return c;
46
+ });
48
47
  // ensure the file exists
49
48
  const fileStat = fs_1.default.statSync(options.input);
50
49
  (0, assert_1.guard)(fileStat.isFile(), `File ${options.input} does not exist or is no file`);
@@ -52,7 +51,7 @@ async function benchmark() {
52
51
  const maxSlices = options['max-slices'] ?? -1;
53
52
  const slicer = new slicer_1.BenchmarkSlicer(options.parser);
54
53
  try {
55
- await slicer.init(request, undefined, options.threshold);
54
+ await slicer.init(request, config, undefined, options.threshold);
56
55
  // ${escape}1F${escape}1G${escape}2K for line reset
57
56
  if (options.slice === 'all') {
58
57
  const count = await slicer.sliceForAll(all_variables_1.DefaultAllVariablesFilter, (i, total, arr) => console.log(`${prefix} Slicing ${i + 1}/${total} [${JSON.stringify(arr[i])}]`), { maxSliceCount: maxSlices });
@@ -66,7 +65,7 @@ async function benchmark() {
66
65
  else {
67
66
  const limit = parseInt(options.slice);
68
67
  console.log(`${prefix} Slicing up to ${limit} possible slices`);
69
- const count = await slicer.sliceForAll(all_variables_1.DefaultAllVariablesFilter, (i, total, arr) => console.log(`${prefix} Slicing ${i + 1}/${total} [${JSON.stringify(arr[i])}]`), { sampleCount: limit, maxSliceCount: maxSlices, sampleStrategy: options['sampling-strategy'] });
68
+ const count = await slicer.sliceForAll(all_variables_1.DefaultAllVariablesFilter, (i, total, arr) => console.log(`${prefix} Slicing ${i + 1}/${total} [${JSON.stringify(arr[i])}]`), { sampleCount: limit, maxSliceCount: maxSlices, sampleStrategy: options['sampling-strategy'], seed: options.seed });
70
69
  console.log(`${prefix} Completed Slicing`);
71
70
  (0, assert_1.guard)(count >= 0, `Number of slices exceeded limit of ${maxSlices} with ${-count} slices, skipping in count`);
72
71
  (0, assert_1.guard)(count > 0, `No possible slices found for ${options.input}, skipping in count`);
@@ -16,6 +16,7 @@ exports.benchmarkOptions = [
16
16
  { name: 'help', alias: 'h', type: Boolean, description: 'Print this usage guide' },
17
17
  { name: 'limit', alias: 'l', type: Number, description: 'Limit the number of files to process (if given, this will choose these files randomly and add the chosen names to the output' },
18
18
  { name: 'runs', alias: 'r', type: Number, description: 'The amount of benchmark runs that should be done, out of which an average will be calculated' },
19
+ { name: 'seed', type: String, description: 'The random seed for sampling the files if a limit is set, and for sampling the slicing criteria if a maximum is set' },
19
20
  { name: 'input', alias: 'i', type: String, description: 'Pass a folder or file as src to read from. Alternatively, pass a single JSON file that contains a list of paths.', multiple: true, defaultOption: true, defaultValue: [], typeLabel: '{underline files/folders}' },
20
21
  { name: 'parallel', alias: 'p', type: String, description: 'Number of parallel executors (defaults to {italic max(cpu.count-1, 1)})', defaultValue: Math.max(os_1.default.cpus().length - 1, 1), typeLabel: '{underline number}' },
21
22
  { name: 'slice', alias: 's', type: String, description: 'Automatically slice for *all* variables (default) or *no* slicing and only parsing/dataflow construction. Numbers will indicate: sample X random slices from all.', defaultValue: 'all', typeLabel: '{underline all/no}' },
@@ -40,6 +41,7 @@ exports.benchmarkHelperOptions = [
40
41
  { name: 'max-slices', type: Number, description: 'If file has more than passed number of slices, the file is not processed', defaultValue: -1, typeLabel: '{underline number}' },
41
42
  { name: 'threshold', alias: 't', type: Number, description: 'How many re-visits of the same node are ok?', defaultValue: undefined, typeLabel: '{underline number}' },
42
43
  { name: 'sampling-strategy', type: String, description: 'Which strategy to use, when sampling is enabled', defaultValue: 'random', typeLabel: '{underline random/equidistant}' },
44
+ { name: 'seed', type: String, description: 'The random seed for sampling the slicing criteria if a maximum is set' },
43
45
  ];
44
46
  exports.exportQuadsOptions = [
45
47
  { name: 'verbose', alias: 'v', type: Boolean, description: 'Run with verbose logging' },
@@ -10,6 +10,7 @@ const files_1 = require("../util/files");
10
10
  const script_1 = require("./common/script");
11
11
  const shell_1 = require("../r-bridge/shell");
12
12
  const retriever_1 = require("../r-bridge/retriever");
13
+ const config_1 = require("../config");
13
14
  const options = (0, script_1.processCommandLineArgs)('export-quads', [], {
14
15
  subtitle: 'Generate RDF N-Quads from the AST of a given R script',
15
16
  examples: [
@@ -17,7 +18,7 @@ const options = (0, script_1.processCommandLineArgs)('export-quads', [], {
17
18
  '{bold --help}'
18
19
  ]
19
20
  });
20
- const shell = new shell_1.RShell();
21
+ const shell = new shell_1.RShell((0, config_1.getEngineConfig)((0, config_1.getConfig)(), 'r-shell'));
21
22
  async function writeQuadForSingleFile(request, output) {
22
23
  const normalized = await (0, retriever_1.retrieveNormalizedAstFromRCode)(request, shell);
23
24
  const serialized = (0, quads_1.serialize2quads)(normalized.ast, { context: request.content });