@eagleoutice/flowr 2.2.15 → 2.3.0

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 (255) hide show
  1. package/README.md +226 -6
  2. package/abstract-interpretation/data-frame/absint-info.d.ts +109 -0
  3. package/abstract-interpretation/data-frame/absint-info.js +31 -0
  4. package/abstract-interpretation/data-frame/absint-visitor.d.ts +59 -0
  5. package/abstract-interpretation/data-frame/absint-visitor.js +173 -0
  6. package/abstract-interpretation/data-frame/domain.d.ts +107 -0
  7. package/abstract-interpretation/data-frame/domain.js +315 -0
  8. package/abstract-interpretation/data-frame/mappers/access-mapper.d.ts +17 -0
  9. package/abstract-interpretation/data-frame/mappers/access-mapper.js +166 -0
  10. package/abstract-interpretation/data-frame/mappers/arguments.d.ts +117 -0
  11. package/abstract-interpretation/data-frame/mappers/arguments.js +188 -0
  12. package/abstract-interpretation/data-frame/mappers/assignment-mapper.d.ts +20 -0
  13. package/abstract-interpretation/data-frame/mappers/assignment-mapper.js +34 -0
  14. package/abstract-interpretation/data-frame/mappers/function-mapper.d.ts +261 -0
  15. package/abstract-interpretation/data-frame/mappers/function-mapper.js +1219 -0
  16. package/abstract-interpretation/data-frame/mappers/replacement-mapper.d.ts +12 -0
  17. package/abstract-interpretation/data-frame/mappers/replacement-mapper.js +206 -0
  18. package/abstract-interpretation/data-frame/resolve-args.d.ts +42 -0
  19. package/abstract-interpretation/data-frame/resolve-args.js +118 -0
  20. package/abstract-interpretation/data-frame/semantics.d.ts +213 -0
  21. package/abstract-interpretation/data-frame/semantics.js +366 -0
  22. package/abstract-interpretation/data-frame/shape-inference.d.ts +38 -0
  23. package/abstract-interpretation/data-frame/shape-inference.js +117 -0
  24. package/benchmark/slicer.d.ts +18 -2
  25. package/benchmark/slicer.js +143 -5
  26. package/benchmark/stats/print.js +123 -45
  27. package/benchmark/stats/size-of.d.ts +7 -0
  28. package/benchmark/stats/size-of.js +1 -0
  29. package/benchmark/stats/stats.d.ts +30 -1
  30. package/benchmark/stats/stats.js +4 -2
  31. package/benchmark/summarizer/data.d.ts +33 -2
  32. package/benchmark/summarizer/first-phase/input.js +5 -1
  33. package/benchmark/summarizer/first-phase/process.d.ts +2 -1
  34. package/benchmark/summarizer/first-phase/process.js +49 -3
  35. package/benchmark/summarizer/second-phase/process.js +101 -3
  36. package/cli/benchmark-app.d.ts +2 -0
  37. package/cli/benchmark-app.js +5 -1
  38. package/cli/benchmark-helper-app.d.ts +2 -0
  39. package/cli/benchmark-helper-app.js +13 -8
  40. package/cli/common/options.js +4 -0
  41. package/cli/export-quads-app.js +2 -1
  42. package/cli/flowr.js +58 -57
  43. package/cli/repl/commands/repl-cfg.js +13 -13
  44. package/cli/repl/commands/repl-commands.js +2 -2
  45. package/cli/repl/commands/repl-dataflow.js +10 -10
  46. package/cli/repl/commands/repl-execute.d.ts +2 -3
  47. package/cli/repl/commands/repl-execute.js +4 -4
  48. package/cli/repl/commands/repl-lineage.js +4 -4
  49. package/cli/repl/commands/repl-main.d.ts +12 -1
  50. package/cli/repl/commands/repl-normalize.js +6 -6
  51. package/cli/repl/commands/repl-parse.js +2 -2
  52. package/cli/repl/commands/repl-query.js +9 -9
  53. package/cli/repl/commands/repl-version.js +1 -1
  54. package/cli/repl/core.d.ts +5 -2
  55. package/cli/repl/core.js +10 -8
  56. package/cli/repl/server/connection.d.ts +3 -1
  57. package/cli/repl/server/connection.js +7 -5
  58. package/cli/repl/server/server.d.ts +3 -2
  59. package/cli/repl/server/server.js +4 -2
  60. package/cli/script-core/statistics-core.d.ts +2 -1
  61. package/cli/script-core/statistics-core.js +2 -2
  62. package/cli/script-core/statistics-helper-core.d.ts +2 -1
  63. package/cli/script-core/statistics-helper-core.js +5 -4
  64. package/cli/slicer-app.js +4 -2
  65. package/cli/statistics-app.js +2 -1
  66. package/cli/statistics-helper-app.js +2 -1
  67. package/config.d.ts +43 -10
  68. package/config.js +47 -43
  69. package/control-flow/cfg-dead-code.js +45 -2
  70. package/control-flow/cfg-simplification.d.ts +2 -0
  71. package/control-flow/control-flow-graph.d.ts +2 -0
  72. package/control-flow/control-flow-graph.js +8 -0
  73. package/control-flow/dfg-cfg-guided-visitor.d.ts +5 -3
  74. package/control-flow/dfg-cfg-guided-visitor.js +15 -4
  75. package/control-flow/extract-cfg.d.ts +4 -2
  76. package/control-flow/extract-cfg.js +4 -3
  77. package/control-flow/semantic-cfg-guided-visitor.d.ts +20 -2
  78. package/control-flow/semantic-cfg-guided-visitor.js +24 -4
  79. package/core/pipeline-executor.d.ts +4 -1
  80. package/core/pipeline-executor.js +6 -5
  81. package/core/steps/all/core/10-normalize.d.ts +2 -0
  82. package/core/steps/all/core/10-normalize.js +1 -1
  83. package/core/steps/all/core/11-normalize-tree-sitter.d.ts +2 -1
  84. package/core/steps/all/core/11-normalize-tree-sitter.js +2 -2
  85. package/core/steps/all/core/20-dataflow.d.ts +2 -1
  86. package/core/steps/all/core/20-dataflow.js +2 -2
  87. package/core/steps/all/static-slicing/00-slice.d.ts +2 -1
  88. package/core/steps/all/static-slicing/00-slice.js +2 -2
  89. package/core/steps/pipeline/default-pipelines.d.ts +32 -31
  90. package/core/steps/pipeline/default-pipelines.js +8 -8
  91. package/core/steps/pipeline-step.d.ts +2 -1
  92. package/dataflow/environments/built-in-config.d.ts +3 -3
  93. package/dataflow/environments/built-in.d.ts +11 -3
  94. package/dataflow/environments/built-in.js +5 -3
  95. package/dataflow/environments/default-builtin-config.js +4 -2
  96. package/dataflow/environments/define.d.ts +2 -1
  97. package/dataflow/environments/define.js +4 -5
  98. package/dataflow/environments/remove.d.ts +6 -0
  99. package/dataflow/environments/remove.js +29 -0
  100. package/dataflow/eval/resolve/alias-tracking.d.ts +7 -2
  101. package/dataflow/eval/resolve/alias-tracking.js +11 -8
  102. package/dataflow/eval/resolve/resolve-argument.d.ts +8 -0
  103. package/dataflow/eval/resolve/resolve-argument.js +118 -0
  104. package/dataflow/eval/resolve/resolve.d.ts +65 -18
  105. package/dataflow/eval/resolve/resolve.js +144 -48
  106. package/dataflow/eval/values/string/string-constants.d.ts +1 -1
  107. package/dataflow/eval/values/string/string-constants.js +7 -2
  108. package/dataflow/extractor.d.ts +2 -1
  109. package/dataflow/extractor.js +2 -1
  110. package/dataflow/internal/process/functions/call/built-in/built-in-access.js +5 -6
  111. package/dataflow/internal/process/functions/call/built-in/built-in-apply.js +1 -1
  112. package/dataflow/internal/process/functions/call/built-in/built-in-assignment.d.ts +4 -2
  113. package/dataflow/internal/process/functions/call/built-in/built-in-assignment.js +11 -11
  114. package/dataflow/internal/process/functions/call/built-in/built-in-eval.js +10 -11
  115. package/dataflow/internal/process/functions/call/built-in/built-in-expression-list.js +7 -2
  116. package/dataflow/internal/process/functions/call/built-in/built-in-for-loop.js +2 -3
  117. package/dataflow/internal/process/functions/call/built-in/built-in-if-then-else.js +1 -1
  118. package/dataflow/internal/process/functions/call/built-in/built-in-list.js +2 -2
  119. package/dataflow/internal/process/functions/call/built-in/built-in-replacement.js +2 -3
  120. package/dataflow/internal/process/functions/call/built-in/built-in-source.d.ts +6 -3
  121. package/dataflow/internal/process/functions/call/built-in/built-in-source.js +19 -15
  122. package/dataflow/internal/process/functions/call/built-in/built-in-vector.js +2 -2
  123. package/dataflow/internal/process/functions/call/built-in/built-in-while-loop.js +1 -1
  124. package/dataflow/internal/process/functions/call/common.js +1 -1
  125. package/dataflow/internal/process/functions/process-parameter.js +1 -1
  126. package/dataflow/origin/dfg-get-symbol-refs.d.ts +21 -0
  127. package/dataflow/origin/dfg-get-symbol-refs.js +50 -0
  128. package/dataflow/processor.d.ts +5 -0
  129. package/documentation/doc-util/doc-cfg.js +4 -3
  130. package/documentation/doc-util/doc-code.d.ts +1 -1
  131. package/documentation/doc-util/doc-dfg.js +3 -2
  132. package/documentation/doc-util/doc-functions.d.ts +24 -0
  133. package/documentation/doc-util/doc-functions.js +65 -0
  134. package/documentation/doc-util/doc-normalized-ast.js +3 -2
  135. package/documentation/doc-util/doc-print.d.ts +5 -0
  136. package/documentation/doc-util/doc-print.js +36 -0
  137. package/documentation/doc-util/doc-query.js +13 -2
  138. package/documentation/doc-util/doc-repl.js +2 -1
  139. package/documentation/doc-util/doc-search.js +3 -2
  140. package/documentation/doc-util/doc-types.d.ts +28 -6
  141. package/documentation/doc-util/doc-types.js +89 -45
  142. package/documentation/print-cfg-wiki.js +6 -7
  143. package/documentation/print-core-wiki.js +5 -5
  144. package/documentation/print-dataflow-graph-wiki.js +10 -10
  145. package/documentation/print-engines-wiki.js +1 -2
  146. package/documentation/print-faq-wiki.js +8 -2
  147. package/documentation/print-interface-wiki.js +12 -2
  148. package/documentation/print-linter-issue.d.ts +1 -0
  149. package/documentation/print-linter-issue.js +71 -0
  150. package/documentation/print-linter-wiki.js +223 -34
  151. package/documentation/print-linting-and-testing-wiki.js +2 -4
  152. package/documentation/print-normalized-ast-wiki.js +3 -3
  153. package/documentation/print-query-wiki.js +18 -2
  154. package/documentation/print-readme.js +24 -1
  155. package/documentation/print-search-wiki.js +1 -2
  156. package/linter/linter-executor.d.ts +3 -1
  157. package/linter/linter-executor.js +3 -2
  158. package/linter/linter-format.d.ts +67 -7
  159. package/linter/linter-format.js +12 -1
  160. package/linter/linter-rules.d.ts +178 -16
  161. package/linter/linter-rules.js +14 -4
  162. package/linter/linter-tags.d.ts +80 -0
  163. package/linter/linter-tags.js +85 -0
  164. package/linter/rules/absolute-path.d.ts +71 -0
  165. package/linter/rules/absolute-path.js +177 -0
  166. package/linter/rules/dataframe-access-validation.d.ts +53 -0
  167. package/linter/rules/dataframe-access-validation.js +116 -0
  168. package/linter/rules/deprecated-functions.d.ts +43 -0
  169. package/linter/rules/deprecated-functions.js +58 -0
  170. package/linter/rules/{2-file-path-validity.d.ts → file-path-validity.d.ts} +16 -6
  171. package/linter/rules/{2-file-path-validity.js → file-path-validity.js} +21 -13
  172. package/linter/rules/naming-convention.d.ts +71 -0
  173. package/linter/rules/naming-convention.js +168 -0
  174. package/linter/rules/seeded-randomness.d.ts +65 -0
  175. package/linter/rules/seeded-randomness.js +122 -0
  176. package/linter/rules/unused-definition.d.ts +41 -0
  177. package/linter/rules/unused-definition.js +105 -0
  178. package/package.json +5 -2
  179. package/queries/base-query-format.d.ts +2 -0
  180. package/queries/catalog/call-context-query/call-context-query-executor.d.ts +1 -1
  181. package/queries/catalog/call-context-query/call-context-query-executor.js +2 -2
  182. package/queries/catalog/cluster-query/cluster-query-format.d.ts +1 -1
  183. package/queries/catalog/config-query/config-query-executor.d.ts +1 -1
  184. package/queries/catalog/config-query/config-query-executor.js +2 -3
  185. package/queries/catalog/control-flow-query/control-flow-query-executor.d.ts +1 -1
  186. package/queries/catalog/control-flow-query/control-flow-query-executor.js +2 -2
  187. package/queries/catalog/control-flow-query/control-flow-query-format.d.ts +1 -1
  188. package/queries/catalog/dataflow-lens-query/dataflow-lens-query-format.d.ts +1 -1
  189. package/queries/catalog/dataflow-query/dataflow-query-format.d.ts +1 -1
  190. package/queries/catalog/dependencies-query/dependencies-query-executor.js +4 -116
  191. package/queries/catalog/dependencies-query/dependencies-query-format.d.ts +1 -1
  192. package/queries/catalog/df-shape-query/df-shape-query-executor.d.ts +3 -0
  193. package/queries/catalog/df-shape-query/df-shape-query-executor.js +46 -0
  194. package/queries/catalog/df-shape-query/df-shape-query-format.d.ts +72 -0
  195. package/queries/catalog/df-shape-query/df-shape-query-format.js +31 -0
  196. package/queries/catalog/happens-before-query/happens-before-query-format.d.ts +1 -1
  197. package/queries/catalog/id-map-query/id-map-query-format.d.ts +1 -1
  198. package/queries/catalog/lineage-query/lineage-query-format.d.ts +1 -1
  199. package/queries/catalog/linter-query/linter-query-executor.d.ts +1 -1
  200. package/queries/catalog/linter-query/linter-query-executor.js +2 -2
  201. package/queries/catalog/linter-query/linter-query-format.d.ts +1 -1
  202. package/queries/catalog/linter-query/linter-query-format.js +16 -12
  203. package/queries/catalog/normalized-ast-query/normalized-ast-query-format.d.ts +1 -1
  204. package/queries/catalog/origin-query/origin-query-format.d.ts +1 -1
  205. package/queries/catalog/project-query/project-query-format.d.ts +1 -1
  206. package/queries/catalog/resolve-value-query/resolve-value-query-executor.d.ts +1 -1
  207. package/queries/catalog/resolve-value-query/resolve-value-query-executor.js +2 -2
  208. package/queries/catalog/resolve-value-query/resolve-value-query-format.d.ts +1 -1
  209. package/queries/catalog/search-query/search-query-executor.d.ts +1 -1
  210. package/queries/catalog/search-query/search-query-executor.js +2 -2
  211. package/queries/catalog/search-query/search-query-format.d.ts +1 -1
  212. package/queries/catalog/static-slice-query/static-slice-query-executor.d.ts +1 -1
  213. package/queries/catalog/static-slice-query/static-slice-query-executor.js +2 -2
  214. package/queries/catalog/static-slice-query/static-slice-query-format.d.ts +1 -1
  215. package/queries/query.d.ts +76 -16
  216. package/queries/query.js +2 -0
  217. package/r-bridge/lang-4.x/ast/parser/json/parser.d.ts +2 -1
  218. package/r-bridge/lang-4.x/ast/parser/json/parser.js +4 -2
  219. package/r-bridge/lang-4.x/convert-values.js +2 -1
  220. package/r-bridge/lang-4.x/tree-sitter/tree-sitter-executor.d.ts +3 -1
  221. package/r-bridge/lang-4.x/tree-sitter/tree-sitter-executor.js +4 -4
  222. package/r-bridge/lang-4.x/tree-sitter/tree-sitter-normalize.d.ts +1 -1
  223. package/r-bridge/lang-4.x/tree-sitter/tree-sitter-normalize.js +7 -5
  224. package/r-bridge/shell.d.ts +3 -2
  225. package/r-bridge/shell.js +4 -5
  226. package/search/flowr-search-builder.d.ts +6 -2
  227. package/search/flowr-search-builder.js +7 -0
  228. package/search/flowr-search-filters.d.ts +32 -8
  229. package/search/flowr-search-filters.js +42 -15
  230. package/search/flowr-search.d.ts +4 -0
  231. package/search/search-executor/search-enrichers.d.ts +7 -3
  232. package/search/search-executor/search-enrichers.js +29 -20
  233. package/search/search-executor/search-generators.js +1 -1
  234. package/search/search-executor/search-transformer.d.ts +2 -0
  235. package/search/search-executor/search-transformer.js +10 -1
  236. package/slicing/static/static-slicer.d.ts +1 -1
  237. package/slicing/static/static-slicer.js +2 -3
  238. package/statistics/statistics.d.ts +3 -1
  239. package/statistics/statistics.js +5 -4
  240. package/util/containers.d.ts +12 -9
  241. package/util/containers.js +12 -9
  242. package/util/files.d.ts +8 -2
  243. package/util/files.js +22 -4
  244. package/util/objects.d.ts +5 -4
  245. package/util/r-value.d.ts +23 -0
  246. package/util/r-value.js +113 -0
  247. package/util/range.d.ts +5 -1
  248. package/util/range.js +11 -3
  249. package/util/text/strings.d.ts +6 -0
  250. package/util/text/strings.js +35 -0
  251. package/util/version.js +1 -1
  252. package/linter/rules/1-deprecated-functions.d.ts +0 -34
  253. package/linter/rules/1-deprecated-functions.js +0 -54
  254. package/util/cfg/cfg.d.ts +0 -0
  255. package/util/cfg/cfg.js +0 -2
@@ -53,6 +53,7 @@ const retriever_1 = require("../../../r-bridge/retriever");
53
53
  const visitor_1 = require("../../../r-bridge/lang-4.x/ast/model/processing/visitor");
54
54
  const type_1 = require("../../../r-bridge/lang-4.x/ast/model/type");
55
55
  const arrays_1 = require("../../../util/collections/arrays");
56
+ const semantics_1 = require("../../../abstract-interpretation/data-frame/semantics");
56
57
  const tempfile = (() => {
57
58
  let _tempfile = undefined;
58
59
  return () => {
@@ -107,10 +108,10 @@ function calculateReductionForSlice(input, dataflow, perSlice, ignoreFluff) {
107
108
  * @see Slicer
108
109
  */
109
110
  async function summarizeSlicerStats(stats, report = () => {
110
- }) {
111
+ }, engineConf) {
111
112
  const collect = new defaultmap_1.DefaultMap(() => []);
112
113
  const sizeOfSliceCriteria = [];
113
- const reParseShellSession = new shell_1.RShell();
114
+ const reParseShellSession = new shell_1.RShell(engineConf);
114
115
  const sliceTimes = [];
115
116
  const reconstructTimes = [];
116
117
  const totalTimes = [];
@@ -250,9 +251,54 @@ async function summarizeSlicerStats(stats, report = () => {
250
251
  normalizedTokensNoComments: (0, summarizer_1.summarizeMeasurement)(sliceSize.normalizedTokensNoComments),
251
252
  dataflowNodes: (0, summarizer_1.summarizeMeasurement)(sliceSize.dataflowNodes)
252
253
  }
253
- }
254
+ },
255
+ dataFrameShape: stats.dataFrameShape ? summarizeDfShapeStats(stats.dataFrameShape) : undefined
256
+ };
257
+ }
258
+ function summarizeDfShapeStats({ perNodeStats, ...stats }) {
259
+ const nodeStats = perNodeStats.values().toArray();
260
+ const isTop = (value) => value === 'top';
261
+ const isInfinite = (value) => value === 'infinite';
262
+ const isBottom = (value) => value === 'bottom';
263
+ const isValue = (value) => value !== undefined && !isTop(value) && !isInfinite(value) && !isBottom(value);
264
+ return {
265
+ ...stats,
266
+ numberOfEntriesPerNode: (0, summarizer_1.summarizeMeasurement)(nodeStats.map(s => s.numberOfEntries)),
267
+ numberOfOperations: (0, arrays_1.arraySum)(nodeStats.map(s => s.mappedOperations?.length).filter(assert_1.isNotUndefined)),
268
+ numberOfTotalValues: nodeStats.filter(s => isValue(s.inferredColNames) && isValue(s.inferredColCount) && isValue(s.inferredRowCount)).length,
269
+ numberOfTotalTop: nodeStats.filter(s => isTop(s.inferredColNames) && isTop(s.inferredColCount) && isTop(s.inferredRowCount)).length,
270
+ numberOfTotalBottom: nodeStats.filter(s => s.inferredColNames === 0 && isBottom(s.inferredColCount) && isBottom(s.inferredRowCount)).length,
271
+ inferredColNames: (0, summarizer_1.summarizeMeasurement)(nodeStats.map(s => s.inferredColNames).filter(isValue)),
272
+ numberOfColNamesValues: nodeStats.map(s => s.inferredColNames).filter(isValue).length,
273
+ numberOfColNamesTop: nodeStats.map(s => s.inferredColNames).filter(isTop).length,
274
+ numberOfColNamesBottom: nodeStats.map(s => s.inferredColNames).filter(number => number === 0).length,
275
+ inferredColCount: (0, summarizer_1.summarizeMeasurement)(nodeStats.map(s => s.inferredColCount).filter(isValue)),
276
+ numberOfColCountExact: nodeStats.map(s => s.approxRangeColCount).filter(range => range === 0).length,
277
+ numberOfColCountValues: nodeStats.map(s => s.inferredColCount).filter(isValue).length,
278
+ numberOfColCountTop: nodeStats.map(s => s.inferredColCount).filter(isTop).length,
279
+ numberOfColCountInfinite: nodeStats.map(s => s.inferredColCount).filter(isInfinite).length,
280
+ numberOfColCountBottom: nodeStats.map(s => s.inferredColCount).filter(isBottom).length,
281
+ approxRangeColCount: (0, summarizer_1.summarizeMeasurement)(nodeStats.map(s => s.approxRangeColCount).filter(assert_1.isNotUndefined).filter(isFinite)),
282
+ inferredRowCount: (0, summarizer_1.summarizeMeasurement)(nodeStats.map(s => s.inferredRowCount).filter(isValue)),
283
+ numberOfRowCountExact: nodeStats.map(s => s.approxRangeRowCount).filter(range => range === 0).length,
284
+ numberOfRowCountValues: nodeStats.map(s => s.inferredRowCount).filter(isValue).length,
285
+ numberOfRowCountTop: nodeStats.map(s => s.inferredRowCount).filter(isTop).length,
286
+ numberOfRowCountInfinite: nodeStats.map(s => s.inferredRowCount).filter(isInfinite).length,
287
+ numberOfRowCountBottom: nodeStats.map(s => s.inferredRowCount).filter(isBottom).length,
288
+ approxRangeRowCount: (0, summarizer_1.summarizeMeasurement)(nodeStats.map(s => s.approxRangeRowCount).filter(assert_1.isNotUndefined).filter(isFinite)),
289
+ perOperationNumber: summarizePerOperationStats(nodeStats),
254
290
  };
255
291
  }
292
+ function summarizePerOperationStats(nodeStats) {
293
+ const perOperationNumber = new Map(semantics_1.DataFrameOperationNames.map(name => [name, 0]));
294
+ for (const stat of nodeStats) {
295
+ for (const operation of stat.mappedOperations ?? []) {
296
+ const value = perOperationNumber.get(operation) ?? 0;
297
+ perOperationNumber.set(operation, value + 1);
298
+ }
299
+ }
300
+ return perOperationNumber;
301
+ }
256
302
  function summarizeSummarizedMeasurement(data) {
257
303
  data = data.filter(assert_1.isNotUndefined);
258
304
  const min = Math.min(...data.map(d => d.min).filter(assert_1.isNotUndefined));
@@ -9,6 +9,8 @@ const defaultmap_1 = require("../../../util/collections/defaultmap");
9
9
  const summarizer_1 = require("../../../util/summarizer");
10
10
  const assert_1 = require("../../../util/assert");
11
11
  const stats_1 = require("../../stats/stats");
12
+ const semantics_1 = require("../../../abstract-interpretation/data-frame/semantics");
13
+ const arrays_1 = require("../../../util/collections/arrays");
12
14
  function summarizeAllSummarizedStats(stats) {
13
15
  const commonMeasurements = new defaultmap_1.DefaultMap(() => []);
14
16
  const perSliceMeasurements = new defaultmap_1.DefaultMap(() => []);
@@ -19,11 +21,14 @@ function summarizeAllSummarizedStats(stats) {
19
21
  const normalizeTimesPerToken = [];
20
22
  const dataflowTimesPerToken = [];
21
23
  const totalCommonTimesPerToken = [];
24
+ const controlFlowTimePerToken = [];
25
+ const dataFrameShapeTimePerToken = [];
22
26
  const memory = new defaultmap_1.DefaultMap(() => []);
23
27
  const reductions = [];
24
28
  const reductionsNoFluff = [];
25
29
  const inputs = [];
26
30
  const dataflows = [];
31
+ const dataFrameShapes = [];
27
32
  let failedToRepParse = 0;
28
33
  let timesHitThreshold = 0;
29
34
  let totalSlices = 0;
@@ -41,6 +46,12 @@ function summarizeAllSummarizedStats(stats) {
41
46
  normalizeTimesPerToken.push(stat.normalizeTimePerToken);
42
47
  dataflowTimesPerToken.push(stat.dataflowTimePerToken);
43
48
  totalCommonTimesPerToken.push(stat.totalCommonTimePerToken);
49
+ if (stat.controlFlowTimePerToken !== undefined) {
50
+ controlFlowTimePerToken.push(stat.controlFlowTimePerToken);
51
+ }
52
+ if (stat.dataFrameShapeTimePerToken !== undefined) {
53
+ dataFrameShapeTimePerToken.push(stat.dataFrameShapeTimePerToken);
54
+ }
44
55
  for (const [k, v] of stat.memory) {
45
56
  memory.get(k).push(v);
46
57
  }
@@ -48,6 +59,9 @@ function summarizeAllSummarizedStats(stats) {
48
59
  reductionsNoFluff.push(stat.perSliceMeasurements.reductionNoFluff);
49
60
  inputs.push(stat.input);
50
61
  dataflows.push(stat.dataflow);
62
+ if (stat.dataFrameShape !== undefined) {
63
+ dataFrameShapes.push(stat.dataFrameShape);
64
+ }
51
65
  failedToRepParse += stat.perSliceMeasurements.failedToRepParse;
52
66
  totalSlices += stat.perSliceMeasurements.numberOfSlices;
53
67
  timesHitThreshold += stat.perSliceMeasurements.timesHitThreshold;
@@ -64,6 +78,8 @@ function summarizeAllSummarizedStats(stats) {
64
78
  normalizeTimePerToken: (0, process_1.summarizeTimePerToken)(normalizeTimesPerToken),
65
79
  dataflowTimePerToken: (0, process_1.summarizeTimePerToken)(dataflowTimesPerToken),
66
80
  totalCommonTimePerToken: (0, process_1.summarizeTimePerToken)(totalCommonTimesPerToken),
81
+ controlFlowTimePerToken: controlFlowTimePerToken.length > 0 ? (0, process_1.summarizeTimePerToken)(controlFlowTimePerToken) : undefined,
82
+ dataFrameShapeTimePerToken: dataFrameShapeTimePerToken.length > 0 ? (0, process_1.summarizeTimePerToken)(dataFrameShapeTimePerToken) : undefined,
67
83
  failedToRepParse,
68
84
  timesHitThreshold,
69
85
  reduction: (0, process_1.summarizeSummarizedReductions)(reductions),
@@ -89,7 +105,43 @@ function summarizeAllSummarizedStats(stats) {
89
105
  storedVertexIndices: (0, summarizer_1.summarizeMeasurement)(dataflows.map(d => d.storedVertexIndices)),
90
106
  storedEnvIndices: (0, summarizer_1.summarizeMeasurement)(dataflows.map(d => d.storedEnvIndices)),
91
107
  overwrittenIndices: (0, summarizer_1.summarizeMeasurement)(dataflows.map(d => d.overwrittenIndices)),
92
- }
108
+ },
109
+ dataFrameShape: stats.some(s => s.dataFrameShape !== undefined) ? {
110
+ numberOfDataFrameFiles: (0, arrays_1.arraySum)(stats.map(s => s.dataFrameShape?.numberOfDataFrameFiles).filter(assert_1.isNotUndefined)),
111
+ numberOfNonDataFrameFiles: (0, arrays_1.arraySum)(stats.map(s => s.dataFrameShape?.numberOfNonDataFrameFiles).filter(assert_1.isNotUndefined)),
112
+ numberOfResultConstraints: (0, summarizer_1.summarizeMeasurement)(stats.map(s => s.dataFrameShape?.numberOfResultConstraints).filter(assert_1.isNotUndefined)),
113
+ numberOfResultingValues: (0, summarizer_1.summarizeMeasurement)(stats.map(s => s.dataFrameShape?.numberOfResultingValues).filter(assert_1.isNotUndefined)),
114
+ numberOfResultingTop: (0, summarizer_1.summarizeMeasurement)(stats.map(s => s.dataFrameShape?.numberOfResultingTop).filter(assert_1.isNotUndefined)),
115
+ numberOfResultingBottom: (0, summarizer_1.summarizeMeasurement)(stats.map(s => s.dataFrameShape?.numberOfResultingBottom).filter(assert_1.isNotUndefined)),
116
+ numberOfEmptyNodes: (0, summarizer_1.summarizeMeasurement)(stats.map(s => s.dataFrameShape?.numberOfEmptyNodes).filter(assert_1.isNotUndefined)),
117
+ numberOfOperationNodes: (0, summarizer_1.summarizeMeasurement)(stats.map(s => s.dataFrameShape?.numberOfOperationNodes).filter(assert_1.isNotUndefined)),
118
+ numberOfValueNodes: (0, summarizer_1.summarizeMeasurement)(stats.map(s => s.dataFrameShape?.numberOfValueNodes).filter(assert_1.isNotUndefined)),
119
+ sizeOfInfo: (0, summarizer_1.summarizeMeasurement)(stats.map(s => s.dataFrameShape?.sizeOfInfo).filter(assert_1.isNotUndefined)),
120
+ numberOfEntriesPerNode: (0, process_1.summarizeSummarizedMeasurement)(stats.map(s => s.dataFrameShape?.numberOfEntriesPerNode).filter(assert_1.isNotUndefined)),
121
+ numberOfOperations: (0, summarizer_1.summarizeMeasurement)(stats.map(s => s.dataFrameShape?.numberOfOperations).filter(assert_1.isNotUndefined)),
122
+ numberOfTotalValues: (0, summarizer_1.summarizeMeasurement)(stats.map(s => s.dataFrameShape?.numberOfTotalValues).filter(assert_1.isNotUndefined)),
123
+ numberOfTotalTop: (0, summarizer_1.summarizeMeasurement)(stats.map(s => s.dataFrameShape?.numberOfTotalTop).filter(assert_1.isNotUndefined)),
124
+ numberOfTotalBottom: (0, summarizer_1.summarizeMeasurement)(stats.map(s => s.dataFrameShape?.numberOfTotalBottom).filter(assert_1.isNotUndefined)),
125
+ inferredColNames: (0, process_1.summarizeSummarizedMeasurement)(stats.map(s => s.dataFrameShape?.inferredColNames).filter(assert_1.isNotUndefined)),
126
+ numberOfColNamesValues: (0, summarizer_1.summarizeMeasurement)(stats.map(s => s.dataFrameShape?.numberOfColNamesValues).filter(assert_1.isNotUndefined)),
127
+ numberOfColNamesTop: (0, summarizer_1.summarizeMeasurement)(stats.map(s => s.dataFrameShape?.numberOfColNamesTop).filter(assert_1.isNotUndefined)),
128
+ numberOfColNamesBottom: (0, summarizer_1.summarizeMeasurement)(stats.map(s => s.dataFrameShape?.numberOfColNamesBottom).filter(assert_1.isNotUndefined)),
129
+ inferredColCount: (0, process_1.summarizeSummarizedMeasurement)(stats.map(s => s.dataFrameShape?.inferredColCount).filter(assert_1.isNotUndefined)),
130
+ numberOfColCountExact: (0, summarizer_1.summarizeMeasurement)(stats.map(s => s.dataFrameShape?.numberOfColCountExact).filter(assert_1.isNotUndefined)),
131
+ numberOfColCountValues: (0, summarizer_1.summarizeMeasurement)(stats.map(s => s.dataFrameShape?.numberOfColCountValues).filter(assert_1.isNotUndefined)),
132
+ numberOfColCountTop: (0, summarizer_1.summarizeMeasurement)(stats.map(s => s.dataFrameShape?.numberOfColCountTop).filter(assert_1.isNotUndefined)),
133
+ numberOfColCountInfinite: (0, summarizer_1.summarizeMeasurement)(stats.map(s => s.dataFrameShape?.numberOfColCountInfinite).filter(assert_1.isNotUndefined)),
134
+ numberOfColCountBottom: (0, summarizer_1.summarizeMeasurement)(stats.map(s => s.dataFrameShape?.numberOfColCountBottom).filter(assert_1.isNotUndefined)),
135
+ approxRangeColCount: (0, process_1.summarizeSummarizedMeasurement)(stats.map(s => s.dataFrameShape?.approxRangeColCount).filter(assert_1.isNotUndefined)),
136
+ inferredRowCount: (0, process_1.summarizeSummarizedMeasurement)(stats.map(s => s.dataFrameShape?.inferredRowCount).filter(assert_1.isNotUndefined)),
137
+ numberOfRowCountExact: (0, summarizer_1.summarizeMeasurement)(stats.map(s => s.dataFrameShape?.numberOfRowCountExact).filter(assert_1.isNotUndefined)),
138
+ numberOfRowCountValues: (0, summarizer_1.summarizeMeasurement)(stats.map(s => s.dataFrameShape?.numberOfRowCountValues).filter(assert_1.isNotUndefined)),
139
+ numberOfRowCountTop: (0, summarizer_1.summarizeMeasurement)(stats.map(s => s.dataFrameShape?.numberOfRowCountTop).filter(assert_1.isNotUndefined)),
140
+ numberOfRowCountInfinite: (0, summarizer_1.summarizeMeasurement)(stats.map(s => s.dataFrameShape?.numberOfRowCountInfinite).filter(assert_1.isNotUndefined)),
141
+ numberOfRowCountBottom: (0, summarizer_1.summarizeMeasurement)(stats.map(s => s.dataFrameShape?.numberOfRowCountBottom).filter(assert_1.isNotUndefined)),
142
+ approxRangeRowCount: (0, process_1.summarizeSummarizedMeasurement)(stats.map(s => s.dataFrameShape?.approxRangeRowCount).filter(assert_1.isNotUndefined)),
143
+ perOperationNumber: new Map(semantics_1.DataFrameOperationNames.map(n => [n, (0, summarizer_1.summarizeMeasurement)(stats.map(s => s.dataFrameShape?.perOperationNumber.get(n) ?? 0))]))
144
+ } : undefined
93
145
  };
94
146
  }
95
147
  function summarizeAllUltimateStats(stats) {
@@ -109,6 +161,8 @@ function summarizeAllUltimateStats(stats) {
109
161
  normalizeTimePerToken: (0, process_1.summarizeSummarizedTimePerToken)(stats.map(s => s.normalizeTimePerToken)),
110
162
  dataflowTimePerToken: (0, process_1.summarizeSummarizedTimePerToken)(stats.map(s => s.dataflowTimePerToken)),
111
163
  totalCommonTimePerToken: (0, process_1.summarizeSummarizedTimePerToken)(stats.map(s => s.totalCommonTimePerToken)),
164
+ controlFlowTimePerToken: stats.some(s => s.controlFlowTimePerToken !== undefined) ? (0, process_1.summarizeSummarizedTimePerToken)(stats.map(s => s.controlFlowTimePerToken).filter(assert_1.isNotUndefined)) : undefined,
165
+ dataFrameShapeTimePerToken: stats.some(s => s.dataFrameShapeTimePerToken !== undefined) ? (0, process_1.summarizeSummarizedTimePerToken)(stats.map(s => s.dataFrameShapeTimePerToken).filter(assert_1.isNotUndefined)) : undefined,
112
166
  reduction: (0, process_1.summarizeSummarizedReductions)(stats.map(s => s.reduction)),
113
167
  reductionNoFluff: (0, process_1.summarizeSummarizedReductions)(stats.map(s => s.reductionNoFluff)),
114
168
  input: {
@@ -132,7 +186,43 @@ function summarizeAllUltimateStats(stats) {
132
186
  storedVertexIndices: (0, process_1.summarizeSummarizedMeasurement)(stats.map(s => s.dataflow.storedVertexIndices)),
133
187
  storedEnvIndices: (0, process_1.summarizeSummarizedMeasurement)(stats.map(s => s.dataflow.storedEnvIndices)),
134
188
  overwrittenIndices: (0, process_1.summarizeSummarizedMeasurement)(stats.map(s => s.dataflow.overwrittenIndices)),
135
- }
189
+ },
190
+ dataFrameShape: stats.some(s => s.dataFrameShape !== undefined) ? {
191
+ numberOfDataFrameFiles: (0, arrays_1.arraySum)(stats.map(s => s.dataFrameShape?.numberOfDataFrameFiles).filter(assert_1.isNotUndefined)),
192
+ numberOfNonDataFrameFiles: (0, arrays_1.arraySum)(stats.map(s => s.dataFrameShape?.numberOfNonDataFrameFiles).filter(assert_1.isNotUndefined)),
193
+ numberOfResultConstraints: (0, process_1.summarizeSummarizedMeasurement)(stats.map(s => s.dataFrameShape?.numberOfResultConstraints).filter(assert_1.isNotUndefined)),
194
+ numberOfResultingValues: (0, process_1.summarizeSummarizedMeasurement)(stats.map(s => s.dataFrameShape?.numberOfResultingValues).filter(assert_1.isNotUndefined)),
195
+ numberOfResultingTop: (0, process_1.summarizeSummarizedMeasurement)(stats.map(s => s.dataFrameShape?.numberOfResultingTop).filter(assert_1.isNotUndefined)),
196
+ numberOfResultingBottom: (0, process_1.summarizeSummarizedMeasurement)(stats.map(s => s.dataFrameShape?.numberOfResultingBottom).filter(assert_1.isNotUndefined)),
197
+ numberOfEmptyNodes: (0, process_1.summarizeSummarizedMeasurement)(stats.map(s => s.dataFrameShape?.numberOfEmptyNodes).filter(assert_1.isNotUndefined)),
198
+ numberOfOperationNodes: (0, process_1.summarizeSummarizedMeasurement)(stats.map(s => s.dataFrameShape?.numberOfOperationNodes).filter(assert_1.isNotUndefined)),
199
+ numberOfValueNodes: (0, process_1.summarizeSummarizedMeasurement)(stats.map(s => s.dataFrameShape?.numberOfValueNodes).filter(assert_1.isNotUndefined)),
200
+ sizeOfInfo: (0, process_1.summarizeSummarizedMeasurement)(stats.map(s => s.dataFrameShape?.sizeOfInfo).filter(assert_1.isNotUndefined)),
201
+ numberOfEntriesPerNode: (0, process_1.summarizeSummarizedMeasurement)(stats.map(s => s.dataFrameShape?.numberOfEntriesPerNode).filter(assert_1.isNotUndefined)),
202
+ numberOfOperations: (0, process_1.summarizeSummarizedMeasurement)(stats.map(s => s.dataFrameShape?.numberOfOperations).filter(assert_1.isNotUndefined)),
203
+ numberOfTotalValues: (0, process_1.summarizeSummarizedMeasurement)(stats.map(s => s.dataFrameShape?.numberOfTotalValues).filter(assert_1.isNotUndefined)),
204
+ numberOfTotalTop: (0, process_1.summarizeSummarizedMeasurement)(stats.map(s => s.dataFrameShape?.numberOfTotalTop).filter(assert_1.isNotUndefined)),
205
+ numberOfTotalBottom: (0, process_1.summarizeSummarizedMeasurement)(stats.map(s => s.dataFrameShape?.numberOfTotalBottom).filter(assert_1.isNotUndefined)),
206
+ inferredColNames: (0, process_1.summarizeSummarizedMeasurement)(stats.map(s => s.dataFrameShape?.inferredColNames).filter(assert_1.isNotUndefined)),
207
+ numberOfColNamesValues: (0, process_1.summarizeSummarizedMeasurement)(stats.map(s => s.dataFrameShape?.numberOfColNamesValues).filter(assert_1.isNotUndefined)),
208
+ numberOfColNamesTop: (0, process_1.summarizeSummarizedMeasurement)(stats.map(s => s.dataFrameShape?.numberOfColNamesTop).filter(assert_1.isNotUndefined)),
209
+ numberOfColNamesBottom: (0, process_1.summarizeSummarizedMeasurement)(stats.map(s => s.dataFrameShape?.numberOfColNamesBottom).filter(assert_1.isNotUndefined)),
210
+ inferredColCount: (0, process_1.summarizeSummarizedMeasurement)(stats.map(s => s.dataFrameShape?.inferredColCount).filter(assert_1.isNotUndefined)),
211
+ numberOfColCountExact: (0, process_1.summarizeSummarizedMeasurement)(stats.map(s => s.dataFrameShape?.numberOfColCountExact).filter(assert_1.isNotUndefined)),
212
+ numberOfColCountValues: (0, process_1.summarizeSummarizedMeasurement)(stats.map(s => s.dataFrameShape?.numberOfColCountValues).filter(assert_1.isNotUndefined)),
213
+ numberOfColCountTop: (0, process_1.summarizeSummarizedMeasurement)(stats.map(s => s.dataFrameShape?.numberOfColCountTop).filter(assert_1.isNotUndefined)),
214
+ numberOfColCountInfinite: (0, process_1.summarizeSummarizedMeasurement)(stats.map(s => s.dataFrameShape?.numberOfColCountInfinite).filter(assert_1.isNotUndefined)),
215
+ numberOfColCountBottom: (0, process_1.summarizeSummarizedMeasurement)(stats.map(s => s.dataFrameShape?.numberOfColCountBottom).filter(assert_1.isNotUndefined)),
216
+ approxRangeColCount: (0, process_1.summarizeSummarizedMeasurement)(stats.map(s => s.dataFrameShape?.approxRangeColCount).filter(assert_1.isNotUndefined)),
217
+ inferredRowCount: (0, process_1.summarizeSummarizedMeasurement)(stats.map(s => s.dataFrameShape?.inferredRowCount).filter(assert_1.isNotUndefined)),
218
+ numberOfRowCountExact: (0, process_1.summarizeSummarizedMeasurement)(stats.map(s => s.dataFrameShape?.numberOfRowCountExact).filter(assert_1.isNotUndefined)),
219
+ numberOfRowCountValues: (0, process_1.summarizeSummarizedMeasurement)(stats.map(s => s.dataFrameShape?.numberOfRowCountValues).filter(assert_1.isNotUndefined)),
220
+ numberOfRowCountTop: (0, process_1.summarizeSummarizedMeasurement)(stats.map(s => s.dataFrameShape?.numberOfRowCountTop).filter(assert_1.isNotUndefined)),
221
+ numberOfRowCountInfinite: (0, process_1.summarizeSummarizedMeasurement)(stats.map(s => s.dataFrameShape?.numberOfRowCountInfinite).filter(assert_1.isNotUndefined)),
222
+ numberOfRowCountBottom: (0, process_1.summarizeSummarizedMeasurement)(stats.map(s => s.dataFrameShape?.numberOfRowCountBottom).filter(assert_1.isNotUndefined)),
223
+ approxRangeRowCount: (0, process_1.summarizeSummarizedMeasurement)(stats.map(s => s.dataFrameShape?.approxRangeRowCount).filter(assert_1.isNotUndefined)),
224
+ perOperationNumber: new Map(semantics_1.DataFrameOperationNames.map(n => [n, (0, process_1.summarizeSummarizedMeasurement)(stats.map(s => s.dataFrameShape?.perOperationNumber.get(n)).filter(assert_1.isNotUndefined))]))
225
+ } : undefined
136
226
  };
137
227
  }
138
228
  function processNextSummary(line, allSummarized) {
@@ -152,7 +242,11 @@ function processNextSummary(line, allSummarized) {
152
242
  ...got.summarize.perSliceMeasurements,
153
243
  // restore maps
154
244
  measurements: new Map(got.summarize.perSliceMeasurements.measurements),
155
- }
245
+ },
246
+ dataFrameShape: got.summarize.dataFrameShape !== undefined ? {
247
+ ...got.summarize.dataFrameShape,
248
+ perOperationNumber: new Map(got.summarize.dataFrameShape.perOperationNumber)
249
+ } : undefined
156
250
  }
157
251
  };
158
252
  allSummarized.push(got.summarize);
@@ -164,6 +258,10 @@ function processNextUltimateSummary(line, allSummarized) {
164
258
  // restore maps
165
259
  commonMeasurements: new Map(got.commonMeasurements),
166
260
  perSliceMeasurements: new Map(got.perSliceMeasurements),
261
+ dataFrameShape: got.dataFrameShape !== undefined ? {
262
+ ...got.dataFrameShape,
263
+ perOperationNumber: new Map(got.dataFrameShape.perOperationNumber)
264
+ } : undefined
167
265
  };
168
266
  allSummarized.push(got);
169
267
  }
@@ -8,7 +8,9 @@ export interface BenchmarkCliOptions {
8
8
  parallel: number;
9
9
  limit?: number;
10
10
  runs?: number;
11
+ seed?: string;
11
12
  parser: KnownParserName;
13
+ 'dataframe-shape-inference': boolean;
12
14
  'enable-pointer-tracking': boolean;
13
15
  'max-file-slices': number;
14
16
  threshold?: 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'] : [];
@@ -67,10 +69,12 @@ async function benchmark() {
67
69
  '--output', path_1.default.join(options.output, path_1.default.relative(f.baseDir, `${f.request.content}.json`)),
68
70
  '--slice', options.slice, ...verboseAdd,
69
71
  '--parser', options.parser,
72
+ ...(options['dataframe-shape-inference'] ? ['--dataframe-shape-inference'] : []),
70
73
  ...(options['enable-pointer-tracking'] ? ['--enable-pointer-tracking'] : []),
71
74
  '--max-slices', `${options['max-file-slices']}`,
72
75
  ...(options.threshold ? ['--threshold', `${options.threshold}`] : []),
73
76
  '--sampling-strategy', options['sampling-strategy'],
77
+ ...(options.seed ? ['--seed', options.seed] : []),
74
78
  ]);
75
79
  const runs = options.runs ?? 1;
76
80
  for (let i = 1; i <= runs; i++) {
@@ -8,8 +8,10 @@ export interface SingleBenchmarkCliOptions {
8
8
  slice: string;
9
9
  output?: string;
10
10
  parser: KnownParserName;
11
+ 'dataframe-shape-inference': boolean;
11
12
  'enable-pointer-tracking': boolean;
12
13
  'max-slices': number;
13
14
  threshold?: number;
14
15
  'sampling-strategy': string;
16
+ seed?: string;
15
17
  }
@@ -39,12 +39,10 @@ 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.amendConfig)((0, config_1.getConfig)(), c => {
43
+ c.solver.pointerTracking = options['enable-pointer-tracking'];
44
+ return c;
45
+ });
48
46
  // ensure the file exists
49
47
  const fileStat = fs_1.default.statSync(options.input);
50
48
  (0, assert_1.guard)(fileStat.isFile(), `File ${options.input} does not exist or is no file`);
@@ -52,7 +50,7 @@ async function benchmark() {
52
50
  const maxSlices = options['max-slices'] ?? -1;
53
51
  const slicer = new slicer_1.BenchmarkSlicer(options.parser);
54
52
  try {
55
- await slicer.init(request, undefined, options.threshold);
53
+ await slicer.init(request, config, undefined, options.threshold);
56
54
  // ${escape}1F${escape}1G${escape}2K for line reset
57
55
  if (options.slice === 'all') {
58
56
  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,11 +64,18 @@ async function benchmark() {
66
64
  else {
67
65
  const limit = parseInt(options.slice);
68
66
  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'] });
67
+ 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
68
  console.log(`${prefix} Completed Slicing`);
71
69
  (0, assert_1.guard)(count >= 0, `Number of slices exceeded limit of ${maxSlices} with ${-count} slices, skipping in count`);
72
70
  (0, assert_1.guard)(count > 0, `No possible slices found for ${options.input}, skipping in count`);
73
71
  }
72
+ if (options['dataframe-shape-inference']) {
73
+ console.log(`${prefix} Extracting control flow graph for data frame shape inference`);
74
+ slicer.extractCFG();
75
+ console.log(`${prefix} Performing shape inference for data frames`);
76
+ slicer.inferDataFrameShapes();
77
+ console.log(`${prefix} Completed data frame shape inference`);
78
+ }
74
79
  const { stats } = slicer.finish();
75
80
  const output = {
76
81
  filename: options.input,
@@ -16,11 +16,13 @@ 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}' },
22
23
  { name: 'output', alias: 'o', type: String, description: `Folder to write all the measurements to in a per-file-basis (defaults to {italic benchmark-${StartTimeString}})`, defaultValue: `benchmark-${StartTimeString}`, typeLabel: '{underline folder}' },
23
24
  { name: 'parser', type: String, description: 'The parser to use for the benchmark', defaultValue: 'r-shell', typeLabel: '{underline parser}' },
25
+ { name: 'dataframe-shape-inference', type: Boolean, description: 'Infer the shape of data frames using abstract interpretation (includes control flow graph extraction)', defaultValue: false },
24
26
  { name: 'enable-pointer-tracking', type: Boolean, description: 'Run dataflow analysis with pointer tracking', defaultValue: false },
25
27
  { name: 'max-file-slices', type: Number, description: 'If file has more than passed number of slices, the file is not processed', defaultValue: -1, typeLabel: '{underline number}' },
26
28
  { name: 'threshold', alias: 't', type: Number, description: 'How many re-visits of the same node are ok?', defaultValue: undefined, typeLabel: '{underline number}' },
@@ -36,10 +38,12 @@ exports.benchmarkHelperOptions = [
36
38
  { 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}' },
37
39
  { name: 'output', alias: 'o', type: String, description: 'File to write the measurements to (appends a single line in JSON format)', typeLabel: '{underline file}' },
38
40
  { name: 'parser', type: String, description: 'The parser to use for the benchmark', defaultValue: 'r-shell', typeLabel: '{underline parser}' },
41
+ { name: 'dataframe-shape-inference', type: Boolean, description: 'Infer the shape of data frames using abstract interpretation (includes control flow graph extraction)', defaultValue: false },
39
42
  { name: 'enable-pointer-tracking', type: Boolean, description: 'Run dataflow analysis with pointer tracking', defaultValue: false },
40
43
  { 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
44
  { name: 'threshold', alias: 't', type: Number, description: 'How many re-visits of the same node are ok?', defaultValue: undefined, typeLabel: '{underline number}' },
42
45
  { name: 'sampling-strategy', type: String, description: 'Which strategy to use, when sampling is enabled', defaultValue: 'random', typeLabel: '{underline random/equidistant}' },
46
+ { name: 'seed', type: String, description: 'The random seed for sampling the slicing criteria if a maximum is set' },
43
47
  ];
44
48
  exports.exportQuadsOptions = [
45
49
  { 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 });
package/cli/flowr.js CHANGED
@@ -52,45 +52,51 @@ if (options['no-ansi']) {
52
52
  log_1.log.info('disabling ansi colors');
53
53
  (0, ansi_1.setFormatter)(ansi_1.voidFormatter);
54
54
  }
55
- let usedConfig = false;
56
- if (options['config-json']) {
57
- const config = (0, config_1.parseConfig)(options['config-json']);
58
- if (config) {
59
- log_1.log.info(`Using passed config ${JSON.stringify(config)}`);
60
- (0, config_1.setConfig)(config);
61
- usedConfig = true;
55
+ function createConfig() {
56
+ let config;
57
+ if (options['config-json']) {
58
+ const passedConfig = (0, config_1.parseConfig)(options['config-json']);
59
+ if (passedConfig) {
60
+ log_1.log.info(`Using passed config ${JSON.stringify(passedConfig)}`);
61
+ config = passedConfig;
62
+ }
62
63
  }
63
- }
64
- if (!usedConfig) {
65
- if (options['config-file']) {
66
- // validate it exists
67
- if (!fs_1.default.existsSync(path_1.default.resolve(options['config-file']))) {
68
- log_1.log.error(`Config file '${options['config-file']}' does not exist`);
69
- process.exit(1);
64
+ if (config == undefined) {
65
+ if (options['config-file']) {
66
+ // validate it exists
67
+ if (!fs_1.default.existsSync(path_1.default.resolve(options['config-file']))) {
68
+ log_1.log.error(`Config file '${options['config-file']}' does not exist`);
69
+ process.exit(1);
70
+ }
70
71
  }
72
+ config = (0, config_1.getConfig)(options['config-file'] ?? flowr_main_options_1.defaultConfigFile);
71
73
  }
72
- (0, config_1.setConfigFile)(options['config-file'] ?? flowr_main_options_1.defaultConfigFile, undefined, true);
73
- }
74
- // for all options that we manually supply that have a config equivalent, set them in the config
75
- if (!options['engine.r-shell.disabled']) {
76
- (0, config_1.amendConfig)({ engines: [{ type: 'r-shell', rPath: options['r-path'] || options['engine.r-shell.r-path'] }] });
77
- }
78
- if (!options['engine.tree-sitter.disabled']) {
79
- (0, config_1.amendConfig)({ engines: [{
74
+ // for all options that we manually supply that have a config equivalent, set them in the config
75
+ config = (0, config_1.amendConfig)(config, c => {
76
+ c.engines ??= [];
77
+ if (!options['engine.r-shell.disabled']) {
78
+ c.engines.push({ type: 'r-shell', rPath: options['r-path'] || options['engine.r-shell.r-path'] });
79
+ }
80
+ if (!options['engine.tree-sitter.disabled']) {
81
+ c.engines.push({
80
82
  type: 'tree-sitter',
81
83
  wasmPath: options['engine.tree-sitter.wasm-path'],
82
84
  treeSitterWasmPath: options['engine.tree-sitter.tree-sitter-wasm-path'],
83
85
  lax: options['engine.tree-sitter.lax']
84
- }] });
85
- }
86
- if (options['default-engine']) {
87
- (0, config_1.amendConfig)({ defaultEngine: options['default-engine'] });
86
+ });
87
+ }
88
+ if (options['default-engine']) {
89
+ c.defaultEngine = options['default-engine'];
90
+ }
91
+ return c;
92
+ });
93
+ return config;
88
94
  }
89
- async function retrieveEngineInstances() {
95
+ async function retrieveEngineInstances(config) {
90
96
  const engines = {};
91
- if ((0, config_1.getEngineConfig)('r-shell')) {
97
+ if ((0, config_1.getEngineConfig)(config, 'r-shell')) {
92
98
  // we keep an active shell session to allow other parse investigations :)
93
- engines['r-shell'] = new shell_1.RShell({
99
+ engines['r-shell'] = new shell_1.RShell((0, config_1.getEngineConfig)(config, 'r-shell'), {
94
100
  revive: 2 /* RShellReviveOptions.Always */,
95
101
  onRevive: (code, signal) => {
96
102
  const signalText = signal == null ? '' : ` and signal ${signal}`;
@@ -99,11 +105,11 @@ async function retrieveEngineInstances() {
99
105
  }
100
106
  });
101
107
  }
102
- if ((0, config_1.getEngineConfig)('tree-sitter')) {
103
- await tree_sitter_executor_1.TreeSitterExecutor.initTreeSitter();
108
+ if ((0, config_1.getEngineConfig)(config, 'tree-sitter')) {
109
+ await tree_sitter_executor_1.TreeSitterExecutor.initTreeSitter((0, config_1.getEngineConfig)(config, 'tree-sitter'));
104
110
  engines['tree-sitter'] = new tree_sitter_executor_1.TreeSitterExecutor();
105
111
  }
106
- let defaultEngine = (0, config_1.getConfig)().defaultEngine;
112
+ let defaultEngine = config.defaultEngine;
107
113
  if (!defaultEngine || !engines[defaultEngine]) {
108
114
  // if a default engine isn't specified, we just take the first one we have
109
115
  defaultEngine = Object.keys(engines)[0];
@@ -111,7 +117,19 @@ async function retrieveEngineInstances() {
111
117
  log_1.log.info(`Using engines ${Object.keys(engines).join(', ')} with default ${defaultEngine}`);
112
118
  return { engines, default: defaultEngine };
113
119
  }
120
+ function hookSignalHandlers(engines) {
121
+ const end = () => {
122
+ if (options.execute === undefined) {
123
+ console.log(`\n${(0, ansi_1.italic)('Exiting...')}`);
124
+ }
125
+ Object.values(engines.engines).forEach(e => e?.close());
126
+ process.exit(0);
127
+ };
128
+ process.on('SIGINT', end);
129
+ process.on('SIGTERM', end);
130
+ }
114
131
  async function mainRepl() {
132
+ const config = createConfig();
115
133
  if (options.script) {
116
134
  const target = scripts_info_1.scripts[options.script].target;
117
135
  (0, assert_1.guard)(target !== undefined, `Unknown script ${options.script}, pick one of ${(0, flowr_main_options_1.getScriptsText)()}.`);
@@ -124,7 +142,7 @@ async function mainRepl() {
124
142
  console.log((0, command_line_usage_1.default)(exports.optionHelp));
125
143
  process.exit(0);
126
144
  }
127
- const engines = await retrieveEngineInstances();
145
+ const engines = await retrieveEngineInstances(config);
128
146
  const defaultEngine = engines.engines[engines.default];
129
147
  if (options.version) {
130
148
  for (const engine of Object.values(engines.engines)) {
@@ -133,39 +151,22 @@ async function mainRepl() {
133
151
  }
134
152
  process.exit(0);
135
153
  }
136
- const end = () => {
137
- if (options.execute === undefined) {
138
- console.log(`\n${(0, ansi_1.italic)('Exiting...')}`);
139
- }
140
- Object.values(engines.engines).forEach(e => e?.close());
141
- process.exit(0);
142
- };
143
- // hook some handlers
144
- process.on('SIGINT', end);
145
- process.on('SIGTERM', end);
154
+ hookSignalHandlers(engines);
146
155
  const allowRSessionAccess = options['r-session-access'] ?? false;
147
156
  if (options.execute) {
148
- await (0, core_1.replProcessAnswer)(repl_main_1.standardReplOutput, options.execute, defaultEngine, allowRSessionAccess);
157
+ await (0, core_1.replProcessAnswer)(config, repl_main_1.standardReplOutput, options.execute, defaultEngine, allowRSessionAccess);
149
158
  }
150
159
  else {
151
160
  await (0, print_version_1.printVersionRepl)(defaultEngine);
152
- await (0, core_1.repl)({ parser: defaultEngine, allowRSessionAccess });
161
+ await (0, core_1.repl)(config, { parser: defaultEngine, allowRSessionAccess });
153
162
  }
154
163
  process.exit(0);
155
164
  }
156
165
  async function mainServer(backend = new net_1.NetServer()) {
157
- const engines = await retrieveEngineInstances();
158
- const end = () => {
159
- if (options.execute === undefined) {
160
- console.log(`\n${(0, ansi_1.italic)('Exiting...')}`);
161
- }
162
- Object.values(engines.engines).forEach(e => e?.close());
163
- process.exit(0);
164
- };
165
- // hook some handlers
166
- process.on('SIGINT', end);
167
- process.on('SIGTERM', end);
168
- await new server_1.FlowRServer(engines.engines, engines.default, options['r-session-access'], backend).start(options.port);
166
+ const config = createConfig();
167
+ const engines = await retrieveEngineInstances(config);
168
+ hookSignalHandlers(engines);
169
+ await new server_1.FlowRServer(engines.engines, engines.default, options['r-session-access'], config, backend).start(options.port);
169
170
  }
170
171
  if (options.server) {
171
172
  void mainServer(options.ws ? new net_1.WebSocketServerWrapper() : new net_1.NetServer());