@eagleoutice/flowr 2.2.11 → 2.2.13

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 (301) hide show
  1. package/README.md +82 -20
  2. package/benchmark/slicer.d.ts +49 -22
  3. package/benchmark/slicer.js +89 -29
  4. package/benchmark/stats/print.js +16 -10
  5. package/benchmark/stats/size-of.js +18 -1
  6. package/benchmark/stats/stats.d.ts +3 -0
  7. package/benchmark/summarizer/first-phase/input.js +1 -1
  8. package/benchmark/summarizer/first-phase/process.js +3 -3
  9. package/benchmark/summarizer/second-phase/process.js +9 -3
  10. package/benchmark/summarizer/summarizer.js +1 -1
  11. package/cli/benchmark-app.d.ts +5 -0
  12. package/cli/benchmark-app.js +49 -6
  13. package/cli/benchmark-helper-app.d.ts +4 -0
  14. package/cli/benchmark-helper-app.js +20 -4
  15. package/cli/common/options.js +15 -6
  16. package/cli/common/script.js +1 -1
  17. package/cli/flowr.js +1 -1
  18. package/cli/repl/commands/repl-cfg.d.ts +2 -0
  19. package/cli/repl/commands/repl-cfg.js +38 -24
  20. package/cli/repl/commands/repl-commands.js +6 -2
  21. package/cli/repl/commands/repl-dataflow.d.ts +2 -0
  22. package/cli/repl/commands/repl-dataflow.js +37 -3
  23. package/cli/repl/commands/repl-execute.js +1 -1
  24. package/cli/repl/commands/repl-main.d.ts +1 -1
  25. package/cli/repl/commands/repl-main.js +1 -1
  26. package/cli/repl/commands/repl-normalize.js +1 -1
  27. package/cli/repl/commands/repl-query.js +2 -2
  28. package/cli/repl/core.js +1 -1
  29. package/cli/repl/prompt.js +1 -1
  30. package/cli/repl/server/connection.js +4 -4
  31. package/cli/repl/server/messages/message-analysis.d.ts +1 -1
  32. package/cli/script-core/statistics-core.js +1 -1
  33. package/cli/script-core/statistics-helper-core.js +4 -4
  34. package/config.d.ts +60 -21
  35. package/config.js +24 -4
  36. package/control-flow/basic-cfg-guided-visitor.d.ts +39 -0
  37. package/control-flow/basic-cfg-guided-visitor.js +114 -0
  38. package/control-flow/cfg-properties.d.ts +26 -0
  39. package/control-flow/cfg-properties.js +100 -0
  40. package/control-flow/cfg-simplification.d.ts +18 -0
  41. package/control-flow/cfg-simplification.js +55 -0
  42. package/control-flow/cfg-to-basic-blocks.d.ts +5 -0
  43. package/control-flow/cfg-to-basic-blocks.js +81 -0
  44. package/control-flow/control-flow-graph.d.ts +247 -0
  45. package/control-flow/control-flow-graph.js +290 -0
  46. package/control-flow/dfg-cfg-guided-visitor.d.ts +32 -0
  47. package/control-flow/dfg-cfg-guided-visitor.js +71 -0
  48. package/control-flow/diff-cfg.d.ts +11 -0
  49. package/control-flow/diff-cfg.js +161 -0
  50. package/control-flow/extract-cfg.d.ts +30 -0
  51. package/control-flow/extract-cfg.js +475 -0
  52. package/control-flow/happens-before.d.ts +7 -0
  53. package/{util/cfg → control-flow}/happens-before.js +3 -3
  54. package/control-flow/semantic-cfg-guided-visitor.d.ts +452 -0
  55. package/control-flow/semantic-cfg-guided-visitor.js +492 -0
  56. package/control-flow/simple-visitor.d.ts +25 -0
  57. package/control-flow/simple-visitor.js +80 -0
  58. package/control-flow/syntax-cfg-guided-visitor.d.ts +128 -0
  59. package/control-flow/syntax-cfg-guided-visitor.js +166 -0
  60. package/core/print/print.d.ts +1 -1
  61. package/core/print/slice-diff-ansi.js +1 -1
  62. package/core/steps/pipeline/create-pipeline.js +1 -1
  63. package/dataflow/environments/built-in-config.d.ts +5 -2
  64. package/dataflow/environments/built-in-config.js +17 -8
  65. package/dataflow/environments/built-in.d.ts +16 -5
  66. package/dataflow/environments/built-in.js +55 -6
  67. package/dataflow/environments/clone.d.ts +5 -0
  68. package/dataflow/environments/clone.js +5 -0
  69. package/dataflow/environments/default-builtin-config.d.ts +2 -0
  70. package/dataflow/environments/default-builtin-config.js +164 -13
  71. package/dataflow/environments/define.d.ts +5 -1
  72. package/dataflow/environments/define.js +36 -10
  73. package/dataflow/environments/overwrite.js +4 -0
  74. package/dataflow/environments/remove.d.ts +6 -0
  75. package/dataflow/environments/remove.js +24 -0
  76. package/dataflow/environments/resolve-by-name.js +16 -5
  77. package/dataflow/extractor.js +2 -2
  78. package/dataflow/graph/dataflowgraph-builder.d.ts +79 -7
  79. package/dataflow/graph/dataflowgraph-builder.js +106 -8
  80. package/dataflow/graph/diff-dataflow-graph.d.ts +16 -0
  81. package/dataflow/graph/{diff.js → diff-dataflow-graph.js} +30 -56
  82. package/dataflow/graph/graph.d.ts +17 -4
  83. package/dataflow/graph/graph.js +51 -12
  84. package/dataflow/graph/vertex.d.ts +59 -4
  85. package/dataflow/graph/vertex.js +32 -0
  86. package/dataflow/internal/linker.d.ts +3 -2
  87. package/dataflow/internal/linker.js +36 -25
  88. package/dataflow/internal/process/functions/call/argument/unpack-argument.d.ts +1 -1
  89. package/dataflow/internal/process/functions/call/argument/unpack-argument.js +1 -1
  90. package/dataflow/internal/process/functions/call/built-in/built-in-access.d.ts +1 -0
  91. package/dataflow/internal/process/functions/call/built-in/built-in-access.js +67 -54
  92. package/dataflow/internal/process/functions/call/built-in/built-in-apply.d.ts +6 -4
  93. package/dataflow/internal/process/functions/call/built-in/built-in-apply.js +108 -21
  94. package/dataflow/internal/process/functions/call/built-in/built-in-assignment.js +54 -17
  95. package/dataflow/internal/process/functions/call/built-in/built-in-eval.d.ts +10 -0
  96. package/dataflow/internal/process/functions/call/built-in/built-in-eval.js +140 -0
  97. package/dataflow/internal/process/functions/call/built-in/built-in-expression-list.js +9 -4
  98. package/dataflow/internal/process/functions/call/built-in/built-in-for-loop.js +3 -2
  99. package/dataflow/internal/process/functions/call/built-in/built-in-function-definition.js +15 -4
  100. package/dataflow/internal/process/functions/call/built-in/built-in-get.js +4 -3
  101. package/dataflow/internal/process/functions/call/built-in/built-in-if-then-else.js +4 -3
  102. package/dataflow/internal/process/functions/call/built-in/built-in-library.js +4 -3
  103. package/dataflow/internal/process/functions/call/built-in/built-in-list.js +51 -17
  104. package/dataflow/internal/process/functions/call/built-in/built-in-pipe.js +1 -1
  105. package/dataflow/internal/process/functions/call/built-in/built-in-quote.js +9 -7
  106. package/dataflow/internal/process/functions/call/built-in/built-in-repeat-loop.js +3 -2
  107. package/dataflow/internal/process/functions/call/built-in/built-in-replacement.d.ts +4 -0
  108. package/dataflow/internal/process/functions/call/built-in/built-in-replacement.js +100 -31
  109. package/dataflow/internal/process/functions/call/built-in/built-in-rm.d.ts +7 -0
  110. package/dataflow/internal/process/functions/call/built-in/built-in-rm.js +41 -0
  111. package/dataflow/internal/process/functions/call/built-in/built-in-source.js +35 -8
  112. package/dataflow/internal/process/functions/call/built-in/built-in-special-bin-op.js +4 -3
  113. package/dataflow/internal/process/functions/call/built-in/built-in-vector.d.ts +15 -0
  114. package/dataflow/internal/process/functions/call/built-in/built-in-vector.js +75 -0
  115. package/dataflow/internal/process/functions/call/built-in/built-in-while-loop.js +3 -3
  116. package/dataflow/internal/process/functions/call/common.d.ts +5 -2
  117. package/dataflow/internal/process/functions/call/common.js +9 -5
  118. package/dataflow/internal/process/functions/call/known-call-handling.d.ts +3 -2
  119. package/dataflow/internal/process/functions/call/known-call-handling.js +2 -1
  120. package/dataflow/internal/process/functions/call/named-call-handling.d.ts +2 -0
  121. package/dataflow/internal/process/functions/call/named-call-handling.js +10 -6
  122. package/dataflow/internal/process/functions/call/unnamed-call-handling.d.ts +1 -0
  123. package/dataflow/internal/process/functions/call/unnamed-call-handling.js +6 -4
  124. package/dataflow/internal/process/process-named-call.d.ts +4 -1
  125. package/dataflow/internal/process/process-named-call.js +8 -5
  126. package/dataflow/origin/dfg-get-origin.d.ts +82 -0
  127. package/dataflow/origin/dfg-get-origin.js +116 -0
  128. package/documentation/doc-util/doc-cfg.d.ts +20 -4
  129. package/documentation/doc-util/doc-cfg.js +41 -7
  130. package/documentation/doc-util/doc-cli-option.js +4 -2
  131. package/documentation/doc-util/doc-code.js +10 -2
  132. package/documentation/doc-util/doc-dfg.js +3 -3
  133. package/documentation/doc-util/doc-escape.d.ts +7 -0
  134. package/documentation/doc-util/doc-escape.js +19 -0
  135. package/documentation/doc-util/doc-files.d.ts +1 -0
  136. package/documentation/doc-util/doc-files.js +2 -1
  137. package/documentation/doc-util/doc-normalized-ast.js +3 -3
  138. package/documentation/doc-util/doc-query.js +2 -2
  139. package/documentation/doc-util/doc-repl.js +1 -1
  140. package/documentation/doc-util/doc-search.js +1 -1
  141. package/documentation/doc-util/doc-server-message.js +2 -2
  142. package/documentation/doc-util/doc-structure.d.ts +1 -0
  143. package/documentation/doc-util/doc-structure.js +5 -0
  144. package/documentation/doc-util/doc-types.d.ts +7 -1
  145. package/documentation/doc-util/doc-types.js +13 -2
  146. package/documentation/print-capabilities-markdown.js +28 -2
  147. package/documentation/print-cfg-wiki.d.ts +1 -0
  148. package/documentation/print-cfg-wiki.js +572 -0
  149. package/documentation/print-core-wiki.js +2 -2
  150. package/documentation/print-dataflow-graph-wiki.js +180 -25
  151. package/documentation/print-engines-wiki.js +1 -1
  152. package/documentation/print-faq-wiki.d.ts +1 -0
  153. package/documentation/print-faq-wiki.js +75 -0
  154. package/documentation/print-interface-wiki.js +2 -1
  155. package/documentation/print-linting-and-testing-wiki.js +52 -36
  156. package/documentation/print-normalized-ast-wiki.js +1 -1
  157. package/documentation/print-onboarding-wiki.d.ts +1 -0
  158. package/documentation/print-onboarding-wiki.js +42 -0
  159. package/documentation/print-query-wiki.js +23 -3
  160. package/documentation/print-readme.js +10 -3
  161. package/package.json +10 -6
  162. package/queries/catalog/call-context-query/call-context-query-executor.js +5 -5
  163. package/queries/catalog/call-context-query/call-context-query-format.d.ts +1 -1
  164. package/queries/catalog/call-context-query/call-context-query-format.js +2 -2
  165. package/queries/catalog/call-context-query/identify-link-to-last-call-relation.d.ts +2 -2
  166. package/queries/catalog/call-context-query/identify-link-to-last-call-relation.js +24 -21
  167. package/queries/catalog/cluster-query/cluster-query-format.d.ts +1 -1
  168. package/queries/catalog/cluster-query/cluster-query-format.js +1 -1
  169. package/queries/catalog/config-query/config-query-format.d.ts +1 -1
  170. package/queries/catalog/config-query/config-query-format.js +2 -2
  171. package/queries/catalog/dataflow-lens-query/dataflow-lens-query-format.d.ts +1 -1
  172. package/queries/catalog/dataflow-lens-query/dataflow-lens-query-format.js +2 -2
  173. package/queries/catalog/dataflow-query/dataflow-query-format.d.ts +1 -1
  174. package/queries/catalog/dataflow-query/dataflow-query-format.js +2 -2
  175. package/queries/catalog/dependencies-query/dependencies-query-executor.js +17 -7
  176. package/queries/catalog/dependencies-query/dependencies-query-format.d.ts +2 -26
  177. package/queries/catalog/dependencies-query/dependencies-query-format.js +4 -147
  178. package/queries/catalog/dependencies-query/function-info/function-info.d.ts +24 -0
  179. package/queries/catalog/dependencies-query/function-info/function-info.js +10 -0
  180. package/queries/catalog/dependencies-query/function-info/library-functions.d.ts +2 -0
  181. package/queries/catalog/dependencies-query/function-info/library-functions.js +18 -0
  182. package/queries/catalog/dependencies-query/function-info/read-functions.d.ts +2 -0
  183. package/queries/catalog/dependencies-query/function-info/read-functions.js +101 -0
  184. package/queries/catalog/dependencies-query/function-info/source-functions.d.ts +2 -0
  185. package/queries/catalog/dependencies-query/function-info/source-functions.js +11 -0
  186. package/queries/catalog/dependencies-query/function-info/write-functions.d.ts +2 -0
  187. package/queries/catalog/dependencies-query/function-info/write-functions.js +87 -0
  188. package/queries/catalog/happens-before-query/happens-before-query-executor.d.ts +1 -1
  189. package/queries/catalog/happens-before-query/happens-before-query-executor.js +4 -4
  190. package/queries/catalog/happens-before-query/happens-before-query-format.d.ts +1 -1
  191. package/queries/catalog/happens-before-query/happens-before-query-format.js +2 -2
  192. package/queries/catalog/id-map-query/id-map-query-format.d.ts +1 -1
  193. package/queries/catalog/id-map-query/id-map-query-format.js +2 -2
  194. package/queries/catalog/lineage-query/lineage-query-format.d.ts +1 -1
  195. package/queries/catalog/lineage-query/lineage-query-format.js +2 -2
  196. package/queries/catalog/location-map-query/location-map-query-format.d.ts +1 -1
  197. package/queries/catalog/location-map-query/location-map-query-format.js +2 -2
  198. package/queries/catalog/normalized-ast-query/normalized-ast-query-format.d.ts +1 -1
  199. package/queries/catalog/normalized-ast-query/normalized-ast-query-format.js +2 -2
  200. package/queries/catalog/origin-query/origin-query-executor.d.ts +5 -0
  201. package/queries/catalog/origin-query/origin-query-executor.js +33 -0
  202. package/queries/catalog/origin-query/origin-query-format.d.ts +71 -0
  203. package/queries/catalog/origin-query/origin-query-format.js +27 -0
  204. package/queries/catalog/project-query/project-query-format.d.ts +1 -1
  205. package/queries/catalog/project-query/project-query-format.js +2 -2
  206. package/queries/catalog/resolve-value-query/resolve-value-query-format.d.ts +1 -1
  207. package/queries/catalog/resolve-value-query/resolve-value-query-format.js +2 -2
  208. package/queries/catalog/search-query/search-query-format.d.ts +1 -1
  209. package/queries/catalog/search-query/search-query-format.js +2 -2
  210. package/queries/catalog/static-slice-query/static-slice-query-format.d.ts +1 -1
  211. package/queries/catalog/static-slice-query/static-slice-query-format.js +2 -2
  212. package/queries/query-print.d.ts +1 -1
  213. package/queries/query-print.js +4 -4
  214. package/queries/query.d.ts +61 -2
  215. package/queries/query.js +3 -1
  216. package/r-bridge/data/data.d.ts +2 -2
  217. package/r-bridge/data/data.js +2 -2
  218. package/r-bridge/lang-4.x/ast/model/nodes/r-number.d.ts +3 -2
  219. package/r-bridge/lang-4.x/ast/model/nodes/r-number.js +5 -0
  220. package/r-bridge/lang-4.x/ast/model/nodes/r-string.d.ts +3 -2
  221. package/r-bridge/lang-4.x/ast/model/nodes/r-string.js +5 -0
  222. package/r-bridge/lang-4.x/ast/model/processing/decorate.d.ts +1 -1
  223. package/r-bridge/lang-4.x/ast/model/processing/decorate.js +1 -1
  224. package/r-bridge/lang-4.x/ast/model/processing/fold.js +3 -1
  225. package/r-bridge/lang-4.x/ast/model/processing/stateful-fold.d.ts +1 -1
  226. package/r-bridge/lang-4.x/ast/parser/main/internal/expression/normalize-expression.js +1 -1
  227. package/r-bridge/lang-4.x/ast/parser/main/internal/functions/normalize-argument.js +1 -1
  228. package/r-bridge/lang-4.x/ast/parser/main/internal/functions/normalize-call.js +1 -1
  229. package/r-bridge/lang-4.x/ast/parser/main/internal/functions/normalize-definition.js +1 -1
  230. package/r-bridge/lang-4.x/ast/parser/main/internal/normalize-access.js +1 -1
  231. package/r-bridge/lang-4.x/ast/parser/main/internal/operators/normalize-binary.js +1 -1
  232. package/r-bridge/lang-4.x/ast/parser/main/internal/structure/normalize-root.js +1 -1
  233. package/r-bridge/lang-4.x/ast/parser/main/internal/values/normalize-symbol.js +1 -1
  234. package/r-bridge/lang-4.x/tree-sitter/tree-sitter-executor.d.ts +2 -2
  235. package/r-bridge/lang-4.x/tree-sitter/tree-sitter-executor.js +4 -4
  236. package/r-bridge/lang-4.x/tree-sitter/tree-sitter-normalize.js +26 -8
  237. package/r-bridge/retriever.js +1 -1
  238. package/search/search-executor/search-generators.d.ts +1 -1
  239. package/search/search-executor/search-transformer.d.ts +1 -1
  240. package/slicing/criterion/collect-all.js +1 -1
  241. package/slicing/static/slice-call.js +13 -3
  242. package/statistics/features/supported/assignments/post-process.js +1 -1
  243. package/statistics/features/supported/defined-functions/post-process.js +2 -2
  244. package/statistics/features/supported/used-functions/post-process.js +1 -1
  245. package/statistics/features/supported/used-packages/post-process.js +2 -2
  246. package/statistics/features/supported/values/post-process.js +2 -2
  247. package/statistics/output/print-stats.js +2 -2
  248. package/statistics/summarizer/post-process/clusterer.d.ts +1 -1
  249. package/statistics/summarizer/post-process/clusterer.js +1 -1
  250. package/statistics/summarizer/post-process/histogram.js +3 -3
  251. package/statistics/summarizer/post-process/post-process-output.js +3 -3
  252. package/statistics/summarizer/second-phase/process.js +2 -2
  253. package/statistics/summarizer/summarizer.js +2 -2
  254. package/util/assert.js +36 -1
  255. package/util/cfg/cfg.d.ts +0 -80
  256. package/util/cfg/cfg.js +0 -549
  257. package/util/{arrays.d.ts → collections/arrays.d.ts} +24 -1
  258. package/util/{arrays.js → collections/arrays.js} +44 -3
  259. package/util/collections/set.js +17 -0
  260. package/util/{list-access.d.ts → containers.d.ts} +24 -4
  261. package/util/{list-access.js → containers.js} +42 -12
  262. package/util/diff-graph.d.ts +47 -0
  263. package/util/diff-graph.js +61 -0
  264. package/util/diff.d.ts +6 -6
  265. package/util/diff.js +1 -1
  266. package/util/mermaid/ast.js +12 -1
  267. package/util/mermaid/cfg.d.ts +9 -2
  268. package/util/mermaid/cfg.js +65 -13
  269. package/util/mermaid/dfg.d.ts +2 -1
  270. package/util/mermaid/dfg.js +26 -10
  271. package/util/mermaid/mermaid.d.ts +2 -0
  272. package/util/mermaid/mermaid.js +6 -0
  273. package/util/parallel.d.ts +2 -1
  274. package/util/parallel.js +11 -2
  275. package/util/prefix.d.ts +13 -0
  276. package/util/prefix.js +34 -0
  277. package/util/quads.js +1 -1
  278. package/util/schema.d.ts +1 -1
  279. package/util/schema.js +1 -1
  280. package/util/summarizer.js +1 -1
  281. package/util/{text.js → text/text.js} +1 -1
  282. package/util/{time.js → text/time.js} +1 -1
  283. package/util/version.js +1 -1
  284. package/dataflow/graph/diff.d.ts +0 -36
  285. package/util/cfg/happens-before.d.ts +0 -7
  286. package/util/cfg/visitor.d.ts +0 -9
  287. package/util/cfg/visitor.js +0 -30
  288. package/util/set.js +0 -31
  289. /package/util/{bimap.d.ts → collections/bimap.d.ts} +0 -0
  290. /package/util/{bimap.js → collections/bimap.js} +0 -0
  291. /package/util/{defaultmap.d.ts → collections/defaultmap.d.ts} +0 -0
  292. /package/util/{defaultmap.js → collections/defaultmap.js} +0 -0
  293. /package/util/{set.d.ts → collections/set.d.ts} +0 -0
  294. /package/util/{ansi.d.ts → text/ansi.d.ts} +0 -0
  295. /package/util/{ansi.js → text/ansi.js} +0 -0
  296. /package/util/{args.d.ts → text/args.d.ts} +0 -0
  297. /package/util/{args.js → text/args.js} +0 -0
  298. /package/util/{strings.d.ts → text/strings.d.ts} +0 -0
  299. /package/util/{strings.js → text/strings.js} +0 -0
  300. /package/util/{text.d.ts → text/text.d.ts} +0 -0
  301. /package/util/{time.d.ts → text/time.d.ts} +0 -0
@@ -0,0 +1,161 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.diffOfControlFlowGraphs = diffOfControlFlowGraphs;
4
+ const json_1 = require("../util/json");
5
+ const diff_graph_1 = require("../util/diff-graph");
6
+ const diff_1 = require("../util/diff");
7
+ const control_flow_graph_1 = require("./control-flow-graph");
8
+ const arrays_1 = require("../util/collections/arrays");
9
+ /**
10
+ * Compare two control flow graphs and return a report on the differences.
11
+ * If you simply want to check whether they equal, use {@link GraphDifferenceReport#isEqual|`<result>.isEqual()`}.
12
+ *
13
+ * @see {@link diffOfDataflowGraphs} - for dataflow graphs
14
+ */
15
+ function diffOfControlFlowGraphs(left, right, config) {
16
+ if (left.graph === right.graph) {
17
+ return new diff_graph_1.GraphDifferenceReport();
18
+ }
19
+ const ctx = (0, diff_graph_1.initDiffContext)(left, right, config);
20
+ diffDataflowGraphs(ctx);
21
+ return ctx.report;
22
+ }
23
+ function diffDataflowGraphs(ctx) {
24
+ diffRootVertices(ctx);
25
+ diffVertices(ctx);
26
+ diffOutgoingEdges(ctx);
27
+ }
28
+ function diffRootVertices(ctx) {
29
+ (0, diff_1.setDifference)(ctx.left.rootIds(), ctx.right.rootIds(), {
30
+ ...ctx,
31
+ position: `${ctx.position}Root vertices differ in graphs. `
32
+ });
33
+ }
34
+ function diffVertices(ctx) {
35
+ const lVert = [...ctx.left.vertices(false)].map(([id, info]) => [id, info]);
36
+ const rVert = [...ctx.right.vertices(false)].map(([id, info]) => [id, info]);
37
+ if (lVert.length < rVert.length && !ctx.config.leftIsSubgraph
38
+ || lVert.length > rVert.length && !ctx.config.rightIsSubgraph) {
39
+ ctx.report.addComment(`Detected different number of vertices! ${ctx.leftname} has ${lVert.length}, ${ctx.rightname} has ${rVert.length}`);
40
+ }
41
+ for (const [id, lInfo] of lVert) {
42
+ const rInfo = ctx.right.getVertex(id, false);
43
+ if (rInfo === undefined) {
44
+ if (!ctx.config.rightIsSubgraph) {
45
+ ctx.report.addComment(`Vertex ${id} is not present in ${ctx.rightname}`, { tag: 'vertex', id });
46
+ }
47
+ continue;
48
+ }
49
+ if (lInfo.type !== rInfo.type) {
50
+ ctx.report.addComment(`Vertex ${id} differs in tags. ${ctx.leftname}: ${lInfo.type} vs. ${ctx.rightname}: ${rInfo.type}`, {
51
+ tag: 'vertex',
52
+ id
53
+ });
54
+ }
55
+ if (lInfo.kind !== undefined || rInfo.kind !== undefined) {
56
+ if (lInfo.kind !== rInfo.kind) {
57
+ ctx.report.addComment(`Vertex ${id} differs in kinds. ${ctx.leftname}: ${String(lInfo.kind)} vs ${ctx.rightname}: ${String(rInfo.kind)}`, {
58
+ tag: 'vertex',
59
+ id
60
+ });
61
+ }
62
+ }
63
+ if (lInfo.callTargets !== undefined || rInfo.callTargets !== undefined) {
64
+ (0, diff_1.setDifference)(new Set(lInfo.callTargets ?? []), new Set(rInfo.callTargets ?? []), {
65
+ ...ctx,
66
+ position: `${ctx.position}Vertex ${id} differs in call targets. `
67
+ });
68
+ }
69
+ if (lInfo.elems !== undefined || rInfo.elems !== undefined) {
70
+ if (!(0, arrays_1.arrayEqual)((lInfo.elems ?? []), (rInfo.elems ?? []), control_flow_graph_1.equalVertex)) {
71
+ ctx.report.addComment(`Vertex ${id} differs in elems.\n ${ctx.leftname}: ${JSON.stringify(lInfo.elems)}\n vs\n ${ctx.rightname}: ${JSON.stringify(rInfo.elems)}`, { tag: 'vertex', id });
72
+ }
73
+ }
74
+ (0, diff_1.setDifference)(new Set(lInfo.mid ?? []), new Set(rInfo.mid ?? []), {
75
+ ...ctx,
76
+ position: `${ctx.position}Vertex ${id} differs in attached mid markers. `
77
+ });
78
+ (0, diff_1.setDifference)(new Set(lInfo.end ?? []), new Set(rInfo.end ?? []), {
79
+ ...ctx,
80
+ position: `${ctx.position}Vertex ${id} differs in attached end markers. `
81
+ });
82
+ if (lInfo.root !== rInfo.root) {
83
+ ctx.report.addComment(`Vertex ${id} differs in root. ${ctx.leftname}: ${JSON.stringify(lInfo.root)} vs ${ctx.rightname}: ${JSON.stringify(rInfo.root)}`, {
84
+ tag: 'vertex',
85
+ id
86
+ });
87
+ }
88
+ (0, diff_1.setDifference)(new Set(lInfo.children), new Set(rInfo.children), {
89
+ ...ctx,
90
+ position: `${ctx.position}Vertex ${id} differs in chilren. `
91
+ });
92
+ }
93
+ }
94
+ function diffOutgoingEdges(ctx) {
95
+ const lEdges = new Map([...ctx.left.edges()]);
96
+ const rEdges = new Map([...ctx.right.edges()]);
97
+ if (lEdges.size < rEdges.size && !ctx.config.leftIsSubgraph || lEdges.size > rEdges.size && !ctx.config.rightIsSubgraph) {
98
+ ctx.report.addComment(`Detected different number of edges! ${ctx.leftname} has ${lEdges.size} (${JSON.stringify(lEdges, json_1.jsonReplacer)}). ${ctx.rightname} has ${rEdges.size} ${JSON.stringify(rEdges, json_1.jsonReplacer)}`);
99
+ }
100
+ for (const [id, edge] of lEdges) {
101
+ /* This has nothing to do with the subset relation as we verify this in the same graph.
102
+ * Yet we still do the check as a subgraph may not have to have all source vertices for edges.
103
+ */
104
+ if (!ctx.left.hasVertex(id)) {
105
+ if (!ctx.config.leftIsSubgraph) {
106
+ ctx.report.addComment(`The source ${id} of edges ${JSON.stringify(edge, json_1.jsonReplacer)} is not present in ${ctx.leftname}. This means that the graph contains an edge but not the corresponding vertex.`);
107
+ continue;
108
+ }
109
+ }
110
+ diffEdges(ctx, id, edge, rEdges.get(id));
111
+ }
112
+ // just to make it both ways in case the length differs
113
+ for (const [id, edge] of rEdges) {
114
+ if (!ctx.right.hasVertex(id)) {
115
+ if (!ctx.config.rightIsSubgraph) {
116
+ ctx.report.addComment(`The source ${id} of edges ${JSON.stringify(edge, json_1.jsonReplacer)} is not present in ${ctx.rightname}. This means that the graph contains an edge but not the corresponding vertex.`);
117
+ continue;
118
+ }
119
+ }
120
+ if (!ctx.config.leftIsSubgraph && !lEdges.has(id)) {
121
+ diffEdges(ctx, id, undefined, edge);
122
+ }
123
+ /* otherwise, we already cover the edge above */
124
+ }
125
+ }
126
+ function diffEdge(edge, otherEdge, ctx, id, target) {
127
+ if (edge.label !== otherEdge.label) {
128
+ ctx.report.addComment(`Edge ${id}->${target} differs in labels. ${ctx.leftname}: ${edge.label} vs ${ctx.rightname}: ${otherEdge.label}`, { tag: 'edge', from: id, to: target });
129
+ }
130
+ if (edge.caused !== otherEdge.caused) {
131
+ ctx.report.addComment(`Edge ${id}->${target} differs in caused. ${ctx.leftname}: ${JSON.stringify(edge.caused)} vs ${ctx.rightname}: ${JSON.stringify(otherEdge.caused)}`, { tag: 'edge', from: id, to: target });
132
+ }
133
+ if (edge.when !== otherEdge.when) {
134
+ ctx.report.addComment(`Edge ${id}->${target} differs in when. ${ctx.leftname}: ${JSON.stringify(edge.when)} vs ${ctx.rightname}: ${JSON.stringify(otherEdge.when)}`, { tag: 'edge', from: id, to: target });
135
+ }
136
+ }
137
+ function diffEdges(ctx, id, lEdges, rEdges) {
138
+ if (lEdges === undefined || rEdges === undefined) {
139
+ if ((lEdges === undefined && !ctx.config.leftIsSubgraph)
140
+ || (rEdges === undefined && !ctx.config.rightIsSubgraph)) {
141
+ ctx.report.addComment(`Vertex ${id} has undefined outgoing edges. ${ctx.leftname}: ${JSON.stringify(lEdges, json_1.jsonReplacer)} vs ${ctx.rightname}: ${JSON.stringify(rEdges, json_1.jsonReplacer)}`, { tag: 'vertex', id });
142
+ }
143
+ return;
144
+ }
145
+ if (lEdges.size < rEdges.size && !ctx.config.leftIsSubgraph
146
+ || lEdges.size > rEdges.size && !ctx.config.rightIsSubgraph) {
147
+ ctx.report.addComment(`Vertex ${id} differs in number of outgoing edges. ${ctx.leftname}: [${[...lEdges.keys()].join(',')}] vs ${ctx.rightname}: [${[...rEdges.keys()].join(',')}] `, { tag: 'vertex', id });
148
+ }
149
+ // order independent compare
150
+ for (const [target, edge] of lEdges) {
151
+ const otherEdge = rEdges.get(target);
152
+ if (otherEdge === undefined) {
153
+ if (!ctx.config.rightIsSubgraph) {
154
+ ctx.report.addComment(`Target of ${id}->${target} in ${ctx.leftname} is not present in ${ctx.rightname}`, { tag: 'edge', from: id, to: target });
155
+ }
156
+ continue;
157
+ }
158
+ diffEdge(edge, otherEdge, ctx, id, target);
159
+ }
160
+ }
161
+ //# sourceMappingURL=diff-cfg.js.map
@@ -0,0 +1,30 @@
1
+ import type { QuadSerializationConfiguration } from '../util/quads';
2
+ import type { NormalizedAst, ParentInformation } from '../r-bridge/lang-4.x/ast/model/processing/decorate';
3
+ import type { DataflowGraph } from '../dataflow/graph/graph';
4
+ import type { ControlFlowInformation } from './control-flow-graph';
5
+ import type { CfgSimplificationPassName } from './cfg-simplification';
6
+ /**
7
+ * Given a normalized AST this approximates the control flow graph of the program.
8
+ * This few is different from the computation of the dataflow graph and may differ,
9
+ * especially because it focuses on intra-procedural analysis.
10
+ *
11
+ * @param ast - the normalized AST
12
+ * @param graph - additional dataflow facts to consider by the control flow extraction
13
+ * @param simplifications - a list of simplification passes to apply to the control flow graph
14
+ *
15
+ * @see {@link extractSimpleCfg} - for a simplified version of this function
16
+ */
17
+ export declare function extractCFG<Info = ParentInformation>(ast: NormalizedAst<Info>, graph?: DataflowGraph, simplifications?: readonly CfgSimplificationPassName[]): ControlFlowInformation;
18
+ /**
19
+ * Simplified version of {@link extractCFG} that is much quicker, but much simpler!
20
+ */
21
+ export declare function extractSimpleCfg<Info = ParentInformation>(ast: NormalizedAst<Info>): ControlFlowInformation<import("./control-flow-graph").CfgSimpleVertex>;
22
+ export declare const ResolvedCallSuffix = "-resolved-call-exit";
23
+ /**
24
+ * Convert a cfg to RDF quads.
25
+ *
26
+ * @see {@link df2quads}
27
+ * @see {@link serialize2quads}
28
+ * @see {@link graph2quads}
29
+ */
30
+ export declare function cfg2quads(cfg: ControlFlowInformation, config: QuadSerializationConfiguration): string;
@@ -0,0 +1,475 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ResolvedCallSuffix = void 0;
4
+ exports.extractCFG = extractCFG;
5
+ exports.extractSimpleCfg = extractSimpleCfg;
6
+ exports.cfg2quads = cfg2quads;
7
+ const quads_1 = require("../util/quads");
8
+ const fold_1 = require("../r-bridge/lang-4.x/ast/model/processing/fold");
9
+ const convert_values_1 = require("../r-bridge/lang-4.x/convert-values");
10
+ const r_function_call_1 = require("../r-bridge/lang-4.x/ast/model/nodes/r-function-call");
11
+ const linker_1 = require("../dataflow/internal/linker");
12
+ const vertex_1 = require("../dataflow/graph/vertex");
13
+ const control_flow_graph_1 = require("./control-flow-graph");
14
+ const cfg_simplification_1 = require("./cfg-simplification");
15
+ const assert_1 = require("../util/assert");
16
+ const cfgFolds = {
17
+ foldNumber: cfgLeaf(control_flow_graph_1.CfgVertexType.Expression),
18
+ foldString: cfgLeaf(control_flow_graph_1.CfgVertexType.Expression),
19
+ foldLogical: cfgLeaf(control_flow_graph_1.CfgVertexType.Expression),
20
+ foldSymbol: cfgLeaf(control_flow_graph_1.CfgVertexType.Expression),
21
+ foldAccess: cfgAccess,
22
+ foldBinaryOp: cfgBinaryOp,
23
+ foldPipe: cfgBinaryOp,
24
+ foldUnaryOp: cfgUnaryOp,
25
+ other: {
26
+ foldComment: cfgIgnore,
27
+ foldLineDirective: cfgIgnore
28
+ },
29
+ loop: {
30
+ foldFor: cfgFor,
31
+ foldRepeat: cfgRepeat,
32
+ foldWhile: cfgWhile,
33
+ foldBreak: cfgBreak,
34
+ foldNext: cfgNext
35
+ },
36
+ foldIfThenElse: cfgIfThenElse,
37
+ foldExprList: cfgExprList,
38
+ functions: {
39
+ foldFunctionDefinition: cfgFunctionDefinition,
40
+ foldFunctionCall: cfgFunctionCall,
41
+ foldParameter: cfgArgumentOrParameter,
42
+ foldArgument: cfgArgumentOrParameter
43
+ }
44
+ };
45
+ function dataflowCfgFolds(dataflowGraph) {
46
+ return {
47
+ ...cfgFolds,
48
+ functions: {
49
+ ...cfgFolds.functions,
50
+ foldFunctionCall: cfgFunctionCallWithDataflow(dataflowGraph)
51
+ }
52
+ };
53
+ }
54
+ /**
55
+ * Given a normalized AST this approximates the control flow graph of the program.
56
+ * This few is different from the computation of the dataflow graph and may differ,
57
+ * especially because it focuses on intra-procedural analysis.
58
+ *
59
+ * @param ast - the normalized AST
60
+ * @param graph - additional dataflow facts to consider by the control flow extraction
61
+ * @param simplifications - a list of simplification passes to apply to the control flow graph
62
+ *
63
+ * @see {@link extractSimpleCfg} - for a simplified version of this function
64
+ */
65
+ function extractCFG(ast, graph, simplifications) {
66
+ return (0, cfg_simplification_1.simplifyControlFlowInformation)((0, fold_1.foldAst)(ast.ast, graph ? dataflowCfgFolds(graph) : cfgFolds), simplifications);
67
+ }
68
+ /**
69
+ * Simplified version of {@link extractCFG} that is much quicker, but much simpler!
70
+ */
71
+ function extractSimpleCfg(ast) {
72
+ return (0, fold_1.foldAst)(ast.ast, cfgFolds);
73
+ }
74
+ function cfgLeaf(type) {
75
+ return (leaf) => {
76
+ const graph = new control_flow_graph_1.ControlFlowGraph();
77
+ graph.addVertex({ id: leaf.info.id, type });
78
+ return { graph, breaks: [], nexts: [], returns: [], exitPoints: [leaf.info.id], entryPoints: [leaf.info.id] };
79
+ };
80
+ }
81
+ function cfgBreak(leaf) {
82
+ return { ...cfgLeaf(control_flow_graph_1.CfgVertexType.Statement)(leaf), breaks: [leaf.info.id], exitPoints: [] };
83
+ }
84
+ function cfgNext(leaf) {
85
+ return { ...cfgLeaf(control_flow_graph_1.CfgVertexType.Statement)(leaf), nexts: [leaf.info.id], exitPoints: [] };
86
+ }
87
+ function cfgIgnore(_leaf) {
88
+ return { graph: new control_flow_graph_1.ControlFlowGraph(), breaks: [], nexts: [], returns: [], exitPoints: [], entryPoints: [] };
89
+ }
90
+ function identifyMayStatementType(node) {
91
+ return node.info.role === "expr-list-child" /* RoleInParent.ExpressionListChild */ ? control_flow_graph_1.CfgVertexType.Statement : control_flow_graph_1.CfgVertexType.Expression;
92
+ }
93
+ function cfgIfThenElse(ifNode, condition, then, otherwise) {
94
+ const graph = new control_flow_graph_1.ControlFlowGraph();
95
+ graph.addVertex({ id: ifNode.info.id, type: identifyMayStatementType(ifNode), mid: [ifNode.info.id + '-condition'], end: [ifNode.info.id + '-exit'] });
96
+ graph.addVertex({ id: ifNode.info.id + '-condition', kind: 'condition', type: control_flow_graph_1.CfgVertexType.MidMarker, root: ifNode.info.id });
97
+ graph.addVertex({ id: ifNode.info.id + '-exit', type: control_flow_graph_1.CfgVertexType.EndMarker, root: ifNode.info.id });
98
+ graph.mergeWith(condition.graph);
99
+ graph.mergeWith(then.graph);
100
+ if (otherwise) {
101
+ graph.mergeWith(otherwise.graph);
102
+ }
103
+ for (const exitPoint of condition.exitPoints) {
104
+ graph.addEdge(ifNode.info.id + '-condition', exitPoint, { label: 0 /* CfgEdgeType.Fd */ });
105
+ }
106
+ for (const entryPoint of then.entryPoints) {
107
+ graph.addEdge(entryPoint, ifNode.info.id + '-condition', { label: 1 /* CfgEdgeType.Cd */, when: convert_values_1.RTrue, caused: ifNode.info.id });
108
+ }
109
+ for (const entryPoint of otherwise?.entryPoints ?? []) {
110
+ graph.addEdge(entryPoint, ifNode.info.id + '-condition', { label: 1 /* CfgEdgeType.Cd */, when: convert_values_1.RFalse, caused: ifNode.info.id });
111
+ }
112
+ for (const entryPoint of condition.entryPoints) {
113
+ graph.addEdge(entryPoint, ifNode.info.id, { label: 0 /* CfgEdgeType.Fd */ });
114
+ }
115
+ for (const exit of [...then.exitPoints, ...otherwise?.exitPoints ?? []]) {
116
+ graph.addEdge(ifNode.info.id + '-exit', exit, { label: 0 /* CfgEdgeType.Fd */ });
117
+ }
118
+ if (!otherwise) {
119
+ graph.addEdge(ifNode.info.id + '-exit', ifNode.info.id + '-condition', { label: 1 /* CfgEdgeType.Cd */, when: convert_values_1.RFalse, caused: ifNode.info.id });
120
+ }
121
+ return {
122
+ graph,
123
+ breaks: [...then.breaks, ...otherwise?.breaks ?? []],
124
+ nexts: [...then.nexts, ...otherwise?.nexts ?? []],
125
+ returns: [...then.returns, ...otherwise?.returns ?? []],
126
+ exitPoints: [ifNode.info.id + '-exit'],
127
+ entryPoints: [ifNode.info.id]
128
+ };
129
+ }
130
+ function cfgRepeat(repeat, body) {
131
+ const graph = body.graph;
132
+ graph.addVertex({ id: repeat.info.id, type: identifyMayStatementType(repeat), end: [repeat.info.id + '-exit'] });
133
+ graph.addVertex({ id: repeat.info.id + '-exit', type: control_flow_graph_1.CfgVertexType.EndMarker, root: repeat.info.id });
134
+ for (const entryPoint of body.entryPoints) {
135
+ graph.addEdge(entryPoint, repeat.info.id, { label: 0 /* CfgEdgeType.Fd */ });
136
+ }
137
+ // loops automatically
138
+ for (const next of [...body.nexts, ...body.exitPoints]) {
139
+ graph.addEdge(repeat.info.id, next, { label: 0 /* CfgEdgeType.Fd */ });
140
+ }
141
+ for (const breakPoint of body.breaks) {
142
+ graph.addEdge(repeat.info.id + '-exit', breakPoint, { label: 0 /* CfgEdgeType.Fd */ });
143
+ }
144
+ return { graph, breaks: [], nexts: [], returns: body.returns, exitPoints: [repeat.info.id + '-exit'], entryPoints: [repeat.info.id] };
145
+ }
146
+ function cfgWhile(whileLoop, condition, body) {
147
+ const graph = condition.graph;
148
+ graph.addVertex({ id: whileLoop.info.id, type: identifyMayStatementType(whileLoop), mid: [whileLoop.info.id + '-condition'], end: [whileLoop.info.id + '-exit'] });
149
+ graph.addVertex({ id: whileLoop.info.id + '-condition', kind: 'condition', type: control_flow_graph_1.CfgVertexType.MidMarker, root: whileLoop.info.id });
150
+ graph.addVertex({ id: whileLoop.info.id + '-exit', type: control_flow_graph_1.CfgVertexType.EndMarker, root: whileLoop.info.id });
151
+ graph.mergeWith(body.graph);
152
+ for (const entry of condition.entryPoints) {
153
+ graph.addEdge(entry, whileLoop.info.id, { label: 0 /* CfgEdgeType.Fd */ });
154
+ }
155
+ for (const exit of condition.exitPoints) {
156
+ graph.addEdge(whileLoop.info.id + '-condition', exit, { label: 0 /* CfgEdgeType.Fd */ });
157
+ }
158
+ for (const entry of body.entryPoints) {
159
+ graph.addEdge(entry, whileLoop.info.id + '-condition', { label: 1 /* CfgEdgeType.Cd */, when: convert_values_1.RTrue, caused: whileLoop.info.id });
160
+ }
161
+ for (const next of [...body.nexts, ...body.exitPoints]) {
162
+ graph.addEdge(whileLoop.info.id, next, { label: 0 /* CfgEdgeType.Fd */ });
163
+ }
164
+ for (const breakPoint of body.breaks) {
165
+ graph.addEdge(whileLoop.info.id + '-exit', breakPoint, { label: 0 /* CfgEdgeType.Fd */ });
166
+ }
167
+ // while can break on the condition as well
168
+ graph.addEdge(whileLoop.info.id + '-exit', whileLoop.info.id + '-condition', { label: 1 /* CfgEdgeType.Cd */, when: convert_values_1.RFalse, caused: whileLoop.info.id });
169
+ return { graph, breaks: [], nexts: [], returns: body.returns, exitPoints: [whileLoop.info.id + '-exit'], entryPoints: [whileLoop.info.id] };
170
+ }
171
+ function cfgFor(forLoop, variable, vector, body) {
172
+ const graph = variable.graph;
173
+ graph.addVertex({ id: forLoop.info.id, type: identifyMayStatementType(forLoop), end: [forLoop.info.id + '-exit'], mid: [forLoop.info.id + '-head'] });
174
+ graph.mergeWith(vector.graph);
175
+ graph.mergeWith(body.graph);
176
+ for (const entry of vector.entryPoints) {
177
+ graph.addEdge(entry, forLoop.info.id, { label: 0 /* CfgEdgeType.Fd */ });
178
+ }
179
+ for (const exit of vector.exitPoints) {
180
+ for (const entry of variable.entryPoints) {
181
+ graph.addEdge(entry, exit, { label: 0 /* CfgEdgeType.Fd */ });
182
+ }
183
+ }
184
+ graph.addVertex({ id: forLoop.info.id + '-head', type: control_flow_graph_1.CfgVertexType.MidMarker, root: forLoop.info.id, kind: 'head' });
185
+ for (const exit of variable.exitPoints) {
186
+ graph.addEdge(forLoop.info.id + '-head', exit, { label: 0 /* CfgEdgeType.Fd */ });
187
+ }
188
+ for (const entry of body.entryPoints) {
189
+ graph.addEdge(entry, forLoop.info.id + '-head', { label: 1 /* CfgEdgeType.Cd */, when: convert_values_1.RTrue, caused: forLoop.info.id });
190
+ }
191
+ for (const next of [...body.nexts, ...body.exitPoints]) {
192
+ graph.addEdge(forLoop.info.id, next, { label: 0 /* CfgEdgeType.Fd */ });
193
+ }
194
+ for (const breakPoint of body.breaks) {
195
+ graph.addEdge(forLoop.info.id + '-exit', breakPoint, { label: 0 /* CfgEdgeType.Fd */ });
196
+ }
197
+ const isNotEndless = body.exitPoints.length > 0 || body.breaks.length > 0;
198
+ if (isNotEndless) {
199
+ graph.addVertex({
200
+ id: forLoop.info.id + '-exit',
201
+ type: control_flow_graph_1.CfgVertexType.EndMarker,
202
+ root: forLoop.info.id
203
+ });
204
+ graph.addEdge(forLoop.info.id + '-exit', forLoop.info.id + '-head', { label: 1 /* CfgEdgeType.Cd */, when: convert_values_1.RFalse, caused: forLoop.info.id });
205
+ }
206
+ return { graph, breaks: [], nexts: [], returns: body.returns, exitPoints: isNotEndless ? [forLoop.info.id + '-exit'] : [], entryPoints: [forLoop.info.id] };
207
+ }
208
+ function cfgFunctionDefinition(fn, params, body) {
209
+ const graph = new control_flow_graph_1.ControlFlowGraph();
210
+ const children = [fn.info.id + '-params', fn.info.id + '-exit'];
211
+ graph.addVertex({ id: fn.info.id + '-params', kind: 'parameters', type: control_flow_graph_1.CfgVertexType.MidMarker, root: fn.info.id }, false);
212
+ graph.addVertex({ id: fn.info.id + '-exit', type: control_flow_graph_1.CfgVertexType.EndMarker, root: fn.info.id }, false);
213
+ graph.addVertex({ id: fn.info.id, children, type: identifyMayStatementType(fn), mid: [fn.info.id + '-params'], end: [fn.info.id + '-exit'] });
214
+ graph.mergeWith(body.graph, true);
215
+ children.push(...body.graph.rootIds());
216
+ for (const param of params) {
217
+ graph.mergeWith(param.graph, true);
218
+ children.push(...param.graph.rootIds());
219
+ for (const entry of param.entryPoints) {
220
+ graph.addEdge(entry, fn.info.id, { label: 0 /* CfgEdgeType.Fd */ });
221
+ }
222
+ for (const exit of param.exitPoints) {
223
+ graph.addEdge(fn.info.id + '-params', exit, { label: 0 /* CfgEdgeType.Fd */ });
224
+ }
225
+ }
226
+ if (params.length === 0) {
227
+ graph.addEdge(fn.info.id + '-params', fn.info.id, { label: 0 /* CfgEdgeType.Fd */ });
228
+ }
229
+ for (const entry of body.entryPoints) {
230
+ graph.addEdge(entry, fn.info.id + '-params', { label: 0 /* CfgEdgeType.Fd */ });
231
+ }
232
+ // breaks and nexts should be illegal but safe is safe i guess
233
+ for (const next of [...body.returns, ...body.breaks, ...body.nexts, ...body.exitPoints]) {
234
+ graph.addEdge(fn.info.id + '-exit', next, { label: 0 /* CfgEdgeType.Fd */ });
235
+ }
236
+ return { graph: graph, breaks: [], nexts: [], returns: [], exitPoints: [fn.info.id], entryPoints: [fn.info.id] };
237
+ }
238
+ function cfgFunctionCall(call, name, args, exit = 'exit') {
239
+ const graph = name.graph;
240
+ const info = { graph, breaks: [...name.breaks], nexts: [...name.nexts], returns: [...name.returns], exitPoints: [call.info.id + '-' + exit], entryPoints: [call.info.id] };
241
+ graph.addVertex({ id: call.info.id, type: identifyMayStatementType(call), mid: [call.info.id + '-name'], end: [call.info.id + '-' + exit] });
242
+ for (const entryPoint of name.entryPoints) {
243
+ graph.addEdge(entryPoint, call.info.id, { label: 0 /* CfgEdgeType.Fd */ });
244
+ }
245
+ graph.addVertex({ id: call.info.id + '-name', kind: 'name', type: control_flow_graph_1.CfgVertexType.MidMarker, root: call.info.id });
246
+ for (const exitPoint of name.exitPoints) {
247
+ graph.addEdge(call.info.id + '-name', exitPoint, { label: 0 /* CfgEdgeType.Fd */ });
248
+ }
249
+ graph.addVertex({ id: call.info.id + '-' + exit, type: control_flow_graph_1.CfgVertexType.EndMarker, root: call.info.id });
250
+ let lastArgExits = [call.info.id + '-name'];
251
+ for (const arg of args) {
252
+ if (arg === r_function_call_1.EmptyArgument) {
253
+ continue;
254
+ }
255
+ graph.mergeWith(arg.graph);
256
+ info.breaks = info.breaks.concat(arg.breaks);
257
+ info.nexts = info.nexts.concat(arg.nexts);
258
+ info.returns = info.returns.concat(arg.returns);
259
+ for (const entry of arg.entryPoints) {
260
+ for (const exit of lastArgExits) {
261
+ graph.addEdge(entry, exit, { label: 0 /* CfgEdgeType.Fd */ });
262
+ }
263
+ }
264
+ lastArgExits = arg.exitPoints;
265
+ }
266
+ for (const exit of lastArgExits) {
267
+ graph.addEdge(call.info.id + '-exit', exit, { label: 0 /* CfgEdgeType.Fd */ });
268
+ }
269
+ // should not contain any breaks, nexts, or returns, (except for the body if something like 'break()')
270
+ return info;
271
+ }
272
+ exports.ResolvedCallSuffix = '-resolved-call-exit';
273
+ function cfgFunctionCallWithDataflow(graph) {
274
+ return (call, name, args) => {
275
+ const baseCFG = cfgFunctionCall(call, name, args);
276
+ /* try to resolve the call and link the target definitions */
277
+ const targets = (0, linker_1.getAllFunctionCallTargets)(call.info.id, graph);
278
+ const exits = [];
279
+ const callVertex = baseCFG.graph.getVertex(call.info.id);
280
+ (0, assert_1.guard)(callVertex !== undefined, 'cfgFunctionCallWithDataflow: call vertex not found');
281
+ for (const target of targets) {
282
+ // we have to filter out non func-call targets as the call targets contains names and call ids
283
+ if ((0, vertex_1.isFunctionDefinitionVertex)(graph.getVertex(target))) {
284
+ callVertex.callTargets ??= new Set();
285
+ callVertex.callTargets.add(target);
286
+ exits.push(target + '-exit');
287
+ }
288
+ }
289
+ if (exits.length > 0) {
290
+ baseCFG.graph.addVertex({
291
+ id: call.info.id + exports.ResolvedCallSuffix,
292
+ type: control_flow_graph_1.CfgVertexType.EndMarker,
293
+ root: call.info.id
294
+ });
295
+ for (const exit of [...baseCFG.exitPoints, ...exits]) {
296
+ baseCFG.graph.addEdge(call.info.id + exports.ResolvedCallSuffix, exit, { label: 0 /* CfgEdgeType.Fd */ });
297
+ }
298
+ return {
299
+ ...baseCFG,
300
+ exitPoints: [call.info.id + exports.ResolvedCallSuffix]
301
+ };
302
+ }
303
+ else {
304
+ return baseCFG;
305
+ }
306
+ };
307
+ }
308
+ function cfgArgumentOrParameter(node, name, value) {
309
+ const graph = new control_flow_graph_1.ControlFlowGraph();
310
+ const info = { graph, breaks: [], nexts: [], returns: [], exitPoints: [node.info.id + '-exit'], entryPoints: [node.info.id] };
311
+ graph.addVertex({ id: node.info.id, type: control_flow_graph_1.CfgVertexType.Expression, mid: [node.info.id + '-before-value'], end: [node.info.id + '-exit'] });
312
+ let currentExitPoint = [node.info.id];
313
+ if (name) {
314
+ graph.mergeWith(name.graph);
315
+ info.breaks = info.breaks.concat(name.breaks);
316
+ info.nexts = info.nexts.concat(name.nexts);
317
+ info.returns = info.returns.concat(name.returns);
318
+ for (const entry of name.entryPoints) {
319
+ graph.addEdge(entry, node.info.id, { label: 0 /* CfgEdgeType.Fd */ });
320
+ }
321
+ currentExitPoint = name.exitPoints;
322
+ }
323
+ graph.addVertex({ id: node.info.id + '-before-value', kind: 'before-value', type: control_flow_graph_1.CfgVertexType.MidMarker, root: node.info.id });
324
+ for (const exitPoints of currentExitPoint) {
325
+ graph.addEdge(node.info.id + '-before-value', exitPoints, { label: 0 /* CfgEdgeType.Fd */ });
326
+ }
327
+ currentExitPoint = [node.info.id + '-before-value'];
328
+ if (value) {
329
+ graph.mergeWith(value.graph);
330
+ info.breaks = info.breaks.concat(value.breaks);
331
+ info.nexts = info.nexts.concat(value.nexts);
332
+ info.returns = info.returns.concat(value.returns);
333
+ for (const exitPoint of currentExitPoint) {
334
+ for (const entry of value.entryPoints) {
335
+ graph.addEdge(entry, exitPoint, { label: 0 /* CfgEdgeType.Fd */ });
336
+ }
337
+ }
338
+ currentExitPoint = value.exitPoints;
339
+ }
340
+ graph.addVertex({ id: node.info.id + '-exit', type: control_flow_graph_1.CfgVertexType.EndMarker, root: node.info.id });
341
+ for (const exit of currentExitPoint) {
342
+ graph.addEdge(node.info.id + '-exit', exit, { label: 0 /* CfgEdgeType.Fd */ });
343
+ }
344
+ return info;
345
+ }
346
+ function cfgBinaryOp(binOp, lhs, rhs) {
347
+ const graph = new control_flow_graph_1.ControlFlowGraph().mergeWith(lhs.graph).mergeWith(rhs.graph);
348
+ const result = { graph, breaks: [...lhs.breaks, ...rhs.breaks], nexts: [...lhs.nexts, ...rhs.nexts], returns: [...lhs.returns, ...rhs.returns], entryPoints: [binOp.info.id], exitPoints: [binOp.info.id + '-exit'] };
349
+ graph.addVertex({ id: binOp.info.id, type: binOp.flavor === 'assignment' ? control_flow_graph_1.CfgVertexType.Statement : control_flow_graph_1.CfgVertexType.Expression, end: [binOp.info.id + '-exit'] });
350
+ graph.addVertex({ id: binOp.info.id + '-exit', type: control_flow_graph_1.CfgVertexType.EndMarker, root: binOp.info.id });
351
+ for (const exitPoint of lhs.exitPoints) {
352
+ for (const entryPoint of rhs.entryPoints) {
353
+ result.graph.addEdge(entryPoint, exitPoint, { label: 0 /* CfgEdgeType.Fd */ });
354
+ }
355
+ }
356
+ for (const entryPoint of lhs.entryPoints) {
357
+ graph.addEdge(entryPoint, binOp.info.id, { label: 0 /* CfgEdgeType.Fd */ });
358
+ }
359
+ for (const exitPoint of rhs.exitPoints) {
360
+ graph.addEdge(binOp.info.id + '-exit', exitPoint, { label: 0 /* CfgEdgeType.Fd */ });
361
+ }
362
+ return result;
363
+ }
364
+ function cfgAccess(access, name, accessors) {
365
+ const result = { ...name };
366
+ const graph = result.graph;
367
+ graph.addVertex({ id: access.info.id, type: control_flow_graph_1.CfgVertexType.Expression, mid: [access.info.id + '-after-name'], end: [access.info.id + '-exit'] });
368
+ result.entryPoints = [access.info.id];
369
+ for (const entry of name.entryPoints) {
370
+ graph.addEdge(entry, access.info.id, { label: 0 /* CfgEdgeType.Fd */ });
371
+ }
372
+ for (const exit of name.exitPoints) {
373
+ graph.addEdge(access.info.id + '-after-name', exit, { label: 0 /* CfgEdgeType.Fd */ });
374
+ }
375
+ graph.addVertex({ id: access.info.id + '-after-name', kind: 'after-name', type: control_flow_graph_1.CfgVertexType.MidMarker, root: access.info.id });
376
+ result.exitPoints = [access.info.id + '-after-name'];
377
+ for (const accessor of accessors) {
378
+ if (accessor === r_function_call_1.EmptyArgument) {
379
+ continue;
380
+ }
381
+ graph.mergeWith(accessor.graph);
382
+ for (const exitPoint of result.exitPoints) {
383
+ for (const entry of accessor.entryPoints) {
384
+ graph.addEdge(entry, exitPoint, { label: 0 /* CfgEdgeType.Fd */ });
385
+ }
386
+ }
387
+ result.exitPoints = accessor.exitPoints;
388
+ result.breaks = result.breaks.concat(accessor.breaks);
389
+ result.nexts = result.nexts.concat(accessor.nexts);
390
+ result.returns = result.returns.concat(accessor.returns);
391
+ }
392
+ for (const exitPoint of result.exitPoints) {
393
+ graph.addEdge(access.info.id + '-exit', exitPoint, { label: 0 /* CfgEdgeType.Fd */ });
394
+ }
395
+ graph.addVertex({ id: access.info.id + '-exit', type: control_flow_graph_1.CfgVertexType.EndMarker, root: access.info.id });
396
+ result.exitPoints = [access.info.id + '-exit'];
397
+ return result;
398
+ }
399
+ function cfgUnaryOp(unary, operand) {
400
+ const graph = operand.graph;
401
+ graph.addVertex({ id: unary.info.id, type: control_flow_graph_1.CfgVertexType.EndMarker, root: unary.info.id });
402
+ for (const entry of operand.exitPoints) {
403
+ graph.addEdge(unary.info.id, entry, { label: 0 /* CfgEdgeType.Fd */ });
404
+ }
405
+ return { ...operand, graph, exitPoints: [unary.info.id] };
406
+ }
407
+ function cfgExprList(node, _grouping, expressions) {
408
+ const result = {
409
+ graph: new control_flow_graph_1.ControlFlowGraph(),
410
+ breaks: [],
411
+ nexts: [],
412
+ returns: [],
413
+ exitPoints: [node.info.id],
414
+ entryPoints: [node.info.id]
415
+ };
416
+ const vtx = { id: node.info.id, type: control_flow_graph_1.CfgVertexType.Expression, end: [] };
417
+ result.graph.addVertex(vtx);
418
+ for (const expression of expressions) {
419
+ for (const previousExitPoint of result.exitPoints) {
420
+ for (const entryPoint of expression.entryPoints) {
421
+ result.graph.addEdge(entryPoint, previousExitPoint, { label: 0 /* CfgEdgeType.Fd */ });
422
+ }
423
+ }
424
+ result.graph.mergeWith(expression.graph);
425
+ result.breaks = result.breaks.concat(expression.breaks);
426
+ result.nexts = result.nexts.concat(expression.nexts);
427
+ result.returns = result.returns.concat(expression.returns);
428
+ result.exitPoints = expression.exitPoints;
429
+ }
430
+ if (result.exitPoints.length > 0) {
431
+ result.graph.addVertex({
432
+ id: node.info.id + '-exit',
433
+ type: control_flow_graph_1.CfgVertexType.EndMarker,
434
+ root: node.info.id
435
+ });
436
+ vtx.end = [node.info.id + '-exit'];
437
+ }
438
+ else {
439
+ vtx.end = undefined;
440
+ }
441
+ for (const exit of result.exitPoints) {
442
+ result.graph.addEdge(node.info.id + '-exit', exit, { label: 0 /* CfgEdgeType.Fd */ });
443
+ }
444
+ result.exitPoints = result.exitPoints.length > 0 ? [node.info.id + '-exit'] : [];
445
+ return result;
446
+ }
447
+ /**
448
+ * Convert a cfg to RDF quads.
449
+ *
450
+ * @see {@link df2quads}
451
+ * @see {@link serialize2quads}
452
+ * @see {@link graph2quads}
453
+ */
454
+ function cfg2quads(cfg, config) {
455
+ return (0, quads_1.graph2quads)({
456
+ rootIds: [...cfg.graph.rootIds()],
457
+ vertices: [...cfg.graph.vertices().entries()]
458
+ .map(([id, v]) => ({
459
+ id,
460
+ children: v.children
461
+ })),
462
+ edges: [...cfg.graph.edges()].flatMap(([fromId, targets]) => [...targets].map(([toId, info]) => ({
463
+ from: fromId,
464
+ to: toId,
465
+ type: info.label,
466
+ when: info.when
467
+ }))),
468
+ entryPoints: cfg.entryPoints,
469
+ exitPoints: cfg.exitPoints,
470
+ breaks: cfg.breaks,
471
+ nexts: cfg.nexts,
472
+ returns: cfg.returns
473
+ }, config);
474
+ }
475
+ //# sourceMappingURL=extract-cfg.js.map
@@ -0,0 +1,7 @@
1
+ import type { NodeId } from '../r-bridge/lang-4.x/ast/model/processing/node-id';
2
+ import { Ternary } from '../util/logic';
3
+ import type { ControlFlowGraph } from './control-flow-graph';
4
+ /**
5
+ * Determines if node `a` happens before node `b` in the control flow graph.
6
+ */
7
+ export declare function happensBefore(cfg: ControlFlowGraph, a: NodeId, b: NodeId): Ternary;