@eagleoutice/flowr 2.2.12 → 2.2.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (282) hide show
  1. package/README.md +82 -20
  2. package/benchmark/slicer.js +2 -2
  3. package/benchmark/summarizer/first-phase/input.js +1 -1
  4. package/benchmark/summarizer/first-phase/process.js +3 -3
  5. package/benchmark/summarizer/second-phase/process.js +1 -1
  6. package/benchmark/summarizer/summarizer.js +1 -1
  7. package/cli/common/options.js +4 -4
  8. package/cli/common/script.js +1 -1
  9. package/cli/flowr.js +1 -1
  10. package/cli/repl/commands/repl-cfg.d.ts +2 -0
  11. package/cli/repl/commands/repl-cfg.js +38 -24
  12. package/cli/repl/commands/repl-commands.js +4 -2
  13. package/cli/repl/commands/repl-dataflow.js +3 -3
  14. package/cli/repl/commands/repl-execute.js +1 -1
  15. package/cli/repl/commands/repl-main.d.ts +1 -1
  16. package/cli/repl/commands/repl-main.js +1 -1
  17. package/cli/repl/commands/repl-normalize.js +1 -1
  18. package/cli/repl/commands/repl-query.js +2 -2
  19. package/cli/repl/core.js +1 -1
  20. package/cli/repl/prompt.js +1 -1
  21. package/cli/repl/server/connection.js +4 -4
  22. package/cli/repl/server/messages/message-analysis.d.ts +1 -1
  23. package/cli/script-core/statistics-core.js +1 -1
  24. package/cli/script-core/statistics-helper-core.js +4 -4
  25. package/config.d.ts +47 -24
  26. package/config.js +3 -3
  27. package/control-flow/basic-cfg-guided-visitor.d.ts +39 -0
  28. package/control-flow/basic-cfg-guided-visitor.js +114 -0
  29. package/control-flow/cfg-properties.d.ts +26 -0
  30. package/control-flow/cfg-properties.js +100 -0
  31. package/control-flow/cfg-simplification.d.ts +18 -0
  32. package/control-flow/cfg-simplification.js +55 -0
  33. package/control-flow/cfg-to-basic-blocks.d.ts +5 -0
  34. package/control-flow/cfg-to-basic-blocks.js +81 -0
  35. package/control-flow/control-flow-graph.d.ts +247 -0
  36. package/control-flow/control-flow-graph.js +290 -0
  37. package/control-flow/dfg-cfg-guided-visitor.d.ts +32 -0
  38. package/control-flow/dfg-cfg-guided-visitor.js +71 -0
  39. package/control-flow/diff-cfg.d.ts +11 -0
  40. package/control-flow/diff-cfg.js +161 -0
  41. package/control-flow/extract-cfg.d.ts +30 -0
  42. package/control-flow/extract-cfg.js +475 -0
  43. package/control-flow/happens-before.d.ts +7 -0
  44. package/{util/cfg → control-flow}/happens-before.js +3 -3
  45. package/control-flow/semantic-cfg-guided-visitor.d.ts +452 -0
  46. package/control-flow/semantic-cfg-guided-visitor.js +492 -0
  47. package/control-flow/simple-visitor.d.ts +25 -0
  48. package/control-flow/simple-visitor.js +80 -0
  49. package/control-flow/syntax-cfg-guided-visitor.d.ts +128 -0
  50. package/control-flow/syntax-cfg-guided-visitor.js +166 -0
  51. package/core/print/print.d.ts +1 -1
  52. package/core/print/slice-diff-ansi.js +1 -1
  53. package/core/steps/pipeline/create-pipeline.js +1 -1
  54. package/dataflow/environments/built-in-config.js +9 -6
  55. package/dataflow/environments/built-in.d.ts +8 -4
  56. package/dataflow/environments/built-in.js +47 -5
  57. package/dataflow/environments/default-builtin-config.d.ts +2 -0
  58. package/dataflow/environments/default-builtin-config.js +81 -14
  59. package/dataflow/environments/resolve-by-name.js +15 -4
  60. package/dataflow/extractor.js +2 -2
  61. package/dataflow/graph/dataflowgraph-builder.d.ts +3 -1
  62. package/dataflow/graph/dataflowgraph-builder.js +4 -2
  63. package/dataflow/graph/diff-dataflow-graph.d.ts +16 -0
  64. package/dataflow/graph/{diff.js → diff-dataflow-graph.js} +30 -56
  65. package/dataflow/graph/graph.d.ts +11 -3
  66. package/dataflow/graph/graph.js +27 -12
  67. package/dataflow/graph/vertex.d.ts +17 -2
  68. package/dataflow/internal/linker.d.ts +3 -2
  69. package/dataflow/internal/linker.js +33 -24
  70. package/dataflow/internal/process/functions/call/argument/unpack-argument.d.ts +1 -1
  71. package/dataflow/internal/process/functions/call/argument/unpack-argument.js +1 -1
  72. package/dataflow/internal/process/functions/call/built-in/built-in-access.js +12 -9
  73. package/dataflow/internal/process/functions/call/built-in/built-in-apply.d.ts +1 -1
  74. package/dataflow/internal/process/functions/call/built-in/built-in-apply.js +84 -16
  75. package/dataflow/internal/process/functions/call/built-in/built-in-assignment.js +23 -16
  76. package/dataflow/internal/process/functions/call/built-in/built-in-eval.js +5 -5
  77. package/dataflow/internal/process/functions/call/built-in/built-in-expression-list.js +9 -4
  78. package/dataflow/internal/process/functions/call/built-in/built-in-for-loop.js +3 -2
  79. package/dataflow/internal/process/functions/call/built-in/built-in-function-definition.js +15 -4
  80. package/dataflow/internal/process/functions/call/built-in/built-in-get.js +4 -3
  81. package/dataflow/internal/process/functions/call/built-in/built-in-if-then-else.js +4 -3
  82. package/dataflow/internal/process/functions/call/built-in/built-in-library.js +4 -3
  83. package/dataflow/internal/process/functions/call/built-in/built-in-list.js +1 -1
  84. package/dataflow/internal/process/functions/call/built-in/built-in-pipe.js +1 -1
  85. package/dataflow/internal/process/functions/call/built-in/built-in-quote.js +9 -7
  86. package/dataflow/internal/process/functions/call/built-in/built-in-repeat-loop.js +3 -2
  87. package/dataflow/internal/process/functions/call/built-in/built-in-replacement.d.ts +1 -0
  88. package/dataflow/internal/process/functions/call/built-in/built-in-replacement.js +19 -4
  89. package/dataflow/internal/process/functions/call/built-in/built-in-rm.js +2 -2
  90. package/dataflow/internal/process/functions/call/built-in/built-in-source.js +19 -4
  91. package/dataflow/internal/process/functions/call/built-in/built-in-special-bin-op.js +4 -3
  92. package/dataflow/internal/process/functions/call/built-in/built-in-vector.js +3 -3
  93. package/dataflow/internal/process/functions/call/built-in/built-in-while-loop.js +3 -3
  94. package/dataflow/internal/process/functions/call/common.d.ts +4 -1
  95. package/dataflow/internal/process/functions/call/common.js +5 -3
  96. package/dataflow/internal/process/functions/call/known-call-handling.d.ts +3 -2
  97. package/dataflow/internal/process/functions/call/known-call-handling.js +2 -1
  98. package/dataflow/internal/process/functions/call/named-call-handling.js +1 -1
  99. package/dataflow/internal/process/functions/call/unnamed-call-handling.d.ts +1 -0
  100. package/dataflow/internal/process/functions/call/unnamed-call-handling.js +6 -4
  101. package/dataflow/internal/process/process-named-call.d.ts +1 -1
  102. package/dataflow/internal/process/process-named-call.js +5 -5
  103. package/dataflow/origin/dfg-get-origin.d.ts +82 -0
  104. package/dataflow/origin/dfg-get-origin.js +116 -0
  105. package/documentation/doc-util/doc-cfg.d.ts +13 -6
  106. package/documentation/doc-util/doc-cfg.js +20 -15
  107. package/documentation/doc-util/doc-cli-option.js +4 -2
  108. package/documentation/doc-util/doc-dfg.js +3 -3
  109. package/documentation/doc-util/doc-escape.d.ts +7 -0
  110. package/documentation/doc-util/doc-escape.js +19 -0
  111. package/documentation/doc-util/doc-files.d.ts +1 -0
  112. package/documentation/doc-util/doc-files.js +2 -1
  113. package/documentation/doc-util/doc-normalized-ast.js +3 -3
  114. package/documentation/doc-util/doc-query.js +2 -2
  115. package/documentation/doc-util/doc-repl.js +1 -1
  116. package/documentation/doc-util/doc-search.js +1 -1
  117. package/documentation/doc-util/doc-server-message.js +2 -2
  118. package/documentation/doc-util/doc-structure.d.ts +1 -0
  119. package/documentation/doc-util/doc-structure.js +5 -0
  120. package/documentation/doc-util/doc-types.d.ts +7 -1
  121. package/documentation/doc-util/doc-types.js +13 -2
  122. package/documentation/print-capabilities-markdown.js +27 -1
  123. package/documentation/print-cfg-wiki.js +508 -20
  124. package/documentation/print-dataflow-graph-wiki.js +180 -25
  125. package/documentation/print-engines-wiki.js +1 -1
  126. package/documentation/print-faq-wiki.d.ts +1 -0
  127. package/documentation/print-faq-wiki.js +75 -0
  128. package/documentation/print-interface-wiki.js +1 -1
  129. package/documentation/print-linter-wiki.d.ts +1 -0
  130. package/documentation/print-linter-wiki.js +76 -0
  131. package/documentation/print-linting-and-testing-wiki.js +52 -36
  132. package/documentation/print-normalized-ast-wiki.js +1 -1
  133. package/documentation/print-onboarding-wiki.d.ts +1 -0
  134. package/documentation/print-onboarding-wiki.js +42 -0
  135. package/documentation/print-query-wiki.js +21 -1
  136. package/documentation/print-readme.js +10 -3
  137. package/linter/linter-executor.d.ts +9 -0
  138. package/linter/linter-executor.js +26 -0
  139. package/linter/linter-format.d.ts +65 -0
  140. package/linter/linter-format.js +9 -0
  141. package/linter/linter-rules.d.ts +42 -0
  142. package/linter/linter-rules.js +14 -0
  143. package/linter/rules/1-deprecated-functions.d.ts +34 -0
  144. package/linter/rules/1-deprecated-functions.js +54 -0
  145. package/linter/rules/2-file-path-validity.d.ts +48 -0
  146. package/linter/rules/2-file-path-validity.js +93 -0
  147. package/package.json +10 -6
  148. package/queries/catalog/call-context-query/call-context-query-executor.js +5 -5
  149. package/queries/catalog/call-context-query/call-context-query-format.d.ts +3 -3
  150. package/queries/catalog/call-context-query/call-context-query-format.js +7 -3
  151. package/queries/catalog/call-context-query/identify-link-to-last-call-relation.d.ts +2 -2
  152. package/queries/catalog/call-context-query/identify-link-to-last-call-relation.js +24 -21
  153. package/queries/catalog/cluster-query/cluster-query-format.d.ts +3 -1
  154. package/queries/catalog/cluster-query/cluster-query-format.js +6 -2
  155. package/queries/catalog/config-query/config-query-format.d.ts +2 -1
  156. package/queries/catalog/config-query/config-query-format.js +4 -3
  157. package/queries/catalog/dataflow-lens-query/dataflow-lens-query-format.d.ts +2 -1
  158. package/queries/catalog/dataflow-lens-query/dataflow-lens-query-format.js +4 -3
  159. package/queries/catalog/dataflow-query/dataflow-query-format.d.ts +3 -1
  160. package/queries/catalog/dataflow-query/dataflow-query-format.js +11 -3
  161. package/queries/catalog/dependencies-query/dependencies-query-executor.js +4 -2
  162. package/queries/catalog/dependencies-query/dependencies-query-format.d.ts +2 -1
  163. package/queries/catalog/dependencies-query/dependencies-query-format.js +12 -3
  164. package/queries/catalog/happens-before-query/happens-before-query-executor.d.ts +1 -1
  165. package/queries/catalog/happens-before-query/happens-before-query-executor.js +4 -4
  166. package/queries/catalog/happens-before-query/happens-before-query-format.d.ts +2 -1
  167. package/queries/catalog/happens-before-query/happens-before-query-format.js +4 -3
  168. package/queries/catalog/id-map-query/id-map-query-format.d.ts +2 -1
  169. package/queries/catalog/id-map-query/id-map-query-format.js +4 -3
  170. package/queries/catalog/lineage-query/lineage-query-format.d.ts +2 -1
  171. package/queries/catalog/lineage-query/lineage-query-format.js +7 -3
  172. package/queries/catalog/linter-query/linter-query-executor.d.ts +3 -0
  173. package/queries/catalog/linter-query/linter-query-executor.js +28 -0
  174. package/queries/catalog/linter-query/linter-query-format.d.ts +80 -0
  175. package/queries/catalog/linter-query/linter-query-format.js +43 -0
  176. package/queries/catalog/location-map-query/location-map-query-format.d.ts +2 -1
  177. package/queries/catalog/location-map-query/location-map-query-format.js +4 -3
  178. package/queries/catalog/normalized-ast-query/normalized-ast-query-format.d.ts +2 -1
  179. package/queries/catalog/normalized-ast-query/normalized-ast-query-format.js +4 -3
  180. package/queries/catalog/origin-query/origin-query-executor.d.ts +5 -0
  181. package/queries/catalog/origin-query/origin-query-executor.js +33 -0
  182. package/queries/catalog/origin-query/origin-query-format.d.ts +73 -0
  183. package/queries/catalog/origin-query/origin-query-format.js +31 -0
  184. package/queries/catalog/project-query/project-query-executor.js +1 -1
  185. package/queries/catalog/project-query/project-query-format.d.ts +2 -1
  186. package/queries/catalog/project-query/project-query-format.js +4 -3
  187. package/queries/catalog/resolve-value-query/resolve-value-query-format.d.ts +2 -1
  188. package/queries/catalog/resolve-value-query/resolve-value-query-format.js +4 -3
  189. package/queries/catalog/search-query/search-query-format.d.ts +2 -1
  190. package/queries/catalog/search-query/search-query-format.js +7 -3
  191. package/queries/catalog/static-slice-query/static-slice-query-format.d.ts +3 -1
  192. package/queries/catalog/static-slice-query/static-slice-query-format.js +11 -3
  193. package/queries/query-print.d.ts +1 -1
  194. package/queries/query-print.js +4 -4
  195. package/queries/query.d.ts +143 -2
  196. package/queries/query.js +5 -1
  197. package/r-bridge/lang-4.x/ast/model/nodes/r-number.d.ts +3 -2
  198. package/r-bridge/lang-4.x/ast/model/nodes/r-number.js +5 -0
  199. package/r-bridge/lang-4.x/ast/model/nodes/r-string.d.ts +3 -2
  200. package/r-bridge/lang-4.x/ast/model/nodes/r-string.js +5 -0
  201. package/r-bridge/lang-4.x/ast/model/processing/decorate.d.ts +1 -1
  202. package/r-bridge/lang-4.x/ast/model/processing/decorate.js +1 -1
  203. package/r-bridge/lang-4.x/ast/model/processing/fold.js +3 -1
  204. package/r-bridge/lang-4.x/ast/model/processing/stateful-fold.d.ts +1 -1
  205. package/r-bridge/lang-4.x/ast/parser/main/internal/expression/normalize-expression.js +1 -1
  206. package/r-bridge/lang-4.x/ast/parser/main/internal/functions/normalize-argument.js +1 -1
  207. package/r-bridge/lang-4.x/ast/parser/main/internal/functions/normalize-call.js +1 -1
  208. package/r-bridge/lang-4.x/ast/parser/main/internal/functions/normalize-definition.js +1 -1
  209. package/r-bridge/lang-4.x/ast/parser/main/internal/normalize-access.js +1 -1
  210. package/r-bridge/lang-4.x/ast/parser/main/internal/operators/normalize-binary.js +1 -1
  211. package/r-bridge/lang-4.x/ast/parser/main/internal/structure/normalize-root.js +1 -1
  212. package/r-bridge/lang-4.x/ast/parser/main/internal/values/normalize-symbol.js +1 -1
  213. package/r-bridge/lang-4.x/tree-sitter/tree-sitter-executor.d.ts +2 -2
  214. package/r-bridge/lang-4.x/tree-sitter/tree-sitter-executor.js +4 -4
  215. package/r-bridge/lang-4.x/tree-sitter/tree-sitter-normalize.js +26 -8
  216. package/r-bridge/retriever.js +2 -2
  217. package/search/flowr-search-builder.d.ts +31 -2
  218. package/search/flowr-search-builder.js +30 -0
  219. package/search/flowr-search.d.ts +7 -1
  220. package/search/search-executor/search-enrichers.d.ts +73 -0
  221. package/search/search-executor/search-enrichers.js +98 -0
  222. package/search/search-executor/search-generators.d.ts +7 -2
  223. package/search/search-executor/search-generators.js +21 -1
  224. package/search/search-executor/search-mappers.d.ts +19 -0
  225. package/search/search-executor/search-mappers.js +21 -0
  226. package/search/search-executor/search-transformer.d.ts +13 -1
  227. package/search/search-executor/search-transformer.js +11 -1
  228. package/slicing/criterion/collect-all.js +1 -1
  229. package/slicing/static/slice-call.js +13 -3
  230. package/statistics/features/supported/assignments/post-process.js +1 -1
  231. package/statistics/features/supported/defined-functions/post-process.js +2 -2
  232. package/statistics/features/supported/used-functions/post-process.js +1 -1
  233. package/statistics/features/supported/used-packages/post-process.js +2 -2
  234. package/statistics/features/supported/values/post-process.js +2 -2
  235. package/statistics/output/print-stats.js +2 -2
  236. package/statistics/summarizer/post-process/clusterer.d.ts +1 -1
  237. package/statistics/summarizer/post-process/clusterer.js +1 -1
  238. package/statistics/summarizer/post-process/histogram.js +3 -3
  239. package/statistics/summarizer/post-process/post-process-output.js +3 -3
  240. package/statistics/summarizer/second-phase/process.js +2 -2
  241. package/statistics/summarizer/summarizer.js +2 -2
  242. package/util/assert.js +36 -1
  243. package/util/cfg/cfg.d.ts +0 -80
  244. package/util/cfg/cfg.js +0 -549
  245. package/util/{arrays.d.ts → collections/arrays.d.ts} +1 -1
  246. package/util/{arrays.js → collections/arrays.js} +3 -3
  247. package/util/collections/set.js +17 -0
  248. package/util/diff-graph.d.ts +47 -0
  249. package/util/diff-graph.js +61 -0
  250. package/util/diff.d.ts +6 -6
  251. package/util/diff.js +1 -1
  252. package/util/mermaid/cfg.d.ts +9 -2
  253. package/util/mermaid/cfg.js +64 -12
  254. package/util/mermaid/dfg.d.ts +2 -1
  255. package/util/mermaid/dfg.js +26 -10
  256. package/util/mermaid/mermaid.d.ts +2 -0
  257. package/util/mermaid/mermaid.js +6 -0
  258. package/util/quads.js +1 -1
  259. package/util/schema.d.ts +1 -1
  260. package/util/schema.js +1 -1
  261. package/util/summarizer.js +1 -1
  262. package/util/{text.js → text/text.js} +1 -1
  263. package/util/{time.js → text/time.js} +1 -1
  264. package/util/version.js +1 -1
  265. package/dataflow/graph/diff.d.ts +0 -36
  266. package/util/cfg/happens-before.d.ts +0 -7
  267. package/util/cfg/visitor.d.ts +0 -9
  268. package/util/cfg/visitor.js +0 -30
  269. package/util/set.js +0 -31
  270. /package/util/{bimap.d.ts → collections/bimap.d.ts} +0 -0
  271. /package/util/{bimap.js → collections/bimap.js} +0 -0
  272. /package/util/{defaultmap.d.ts → collections/defaultmap.d.ts} +0 -0
  273. /package/util/{defaultmap.js → collections/defaultmap.js} +0 -0
  274. /package/util/{set.d.ts → collections/set.d.ts} +0 -0
  275. /package/util/{ansi.d.ts → text/ansi.d.ts} +0 -0
  276. /package/util/{ansi.js → text/ansi.js} +0 -0
  277. /package/util/{args.d.ts → text/args.d.ts} +0 -0
  278. /package/util/{args.js → text/args.js} +0 -0
  279. /package/util/{strings.d.ts → text/strings.d.ts} +0 -0
  280. /package/util/{strings.js → text/strings.js} +0 -0
  281. /package/util/{text.d.ts → text/text.d.ts} +0 -0
  282. /package/util/{time.d.ts → text/time.d.ts} +0 -0
@@ -0,0 +1,492 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SemanticCfgGuidedVisitor = void 0;
4
+ const dfg_cfg_guided_visitor_1 = require("./dfg-cfg-guided-visitor");
5
+ const dfg_get_origin_1 = require("../dataflow/origin/dfg-get-origin");
6
+ const type_1 = require("../r-bridge/lang-4.x/ast/model/type");
7
+ const edge_1 = require("../dataflow/graph/edge");
8
+ const assert_1 = require("../util/assert");
9
+ /**
10
+ * This visitor extends on the {@link DataflowAwareCfgGuidedVisitor} by dispatching visitors for separate function calls as well,
11
+ * providing more information!
12
+ * In a way, this is the mixin of syntactic and dataflow guided visitation.
13
+ *
14
+ * Overwrite the functions starting with `on` to implement your logic.
15
+ * In general, there is just one special case that you need to be aware of:
16
+ *
17
+ * In the context of a function call, flowR may be unsure to which origin the call relates!
18
+ * Consider the following example:
19
+ *
20
+ * ```r
21
+ * if(u) foo <- library else foo <- rm
22
+ * foo(x)
23
+ * ```
24
+ *
25
+ * Obtaining the origins of the call to `foo` will return both built-in functions `library` and `rm`.
26
+ * The general semantic visitor cannot decide on how to combine these cases,
27
+ * and it is up to your overload of {@link SemanticCfgGuidedVisitor#onDispatchFunctionCallOrigins|onDispatchFunctionCallOrigins}
28
+ * to decide how to handle this.
29
+ *
30
+ * Use {@link BasicCfgGuidedVisitor#start} to start the traversal.
31
+ */
32
+ class SemanticCfgGuidedVisitor extends dfg_cfg_guided_visitor_1.DataflowAwareCfgGuidedVisitor {
33
+ /**
34
+ * A helper function to get the normalized AST node for the given id or fail if it does not exist.
35
+ */
36
+ getNormalizedAst(id) {
37
+ return this.config.normalizedAst.idMap.get(id);
38
+ }
39
+ /**
40
+ * See {@link DataflowAwareCfgGuidedVisitor#visitValue} for the base implementation.
41
+ * This now dispatches the value to the appropriate event handler based on its type.
42
+ */
43
+ visitValue(val) {
44
+ super.visitValue(val);
45
+ const astNode = this.getNormalizedAst(val.id);
46
+ if (!astNode) {
47
+ return;
48
+ }
49
+ switch (astNode.type) {
50
+ case type_1.RType.String: return this.onStringConstant({ vertex: val, node: astNode });
51
+ case type_1.RType.Number: return this.onNumberConstant({ vertex: val, node: astNode });
52
+ case type_1.RType.Logical: return this.onLogicalConstant({ vertex: val, node: astNode });
53
+ case type_1.RType.Symbol:
54
+ (0, assert_1.guard)(astNode.lexeme === 'NULL', `Expected NULL constant, got ${astNode.lexeme}`);
55
+ return this.onNullConstant({ vertex: val, node: astNode });
56
+ }
57
+ (0, assert_1.guard)(false, `Unexpected value type ${astNode.type} for value ${astNode.lexeme}`);
58
+ }
59
+ /**
60
+ * See {@link DataflowAwareCfgGuidedVisitor#visitVariableUse} for the base implementation.
61
+ *
62
+ * This function is called for every use of a variable in the program and dispatches the appropriate event.
63
+ * You probably do not have to overwrite it and just use {@link SemanticCfgGuidedVisitor#onVariableUse|`onVariableUse`} instead.
64
+ *
65
+ * @protected
66
+ */
67
+ visitVariableUse(vertex) {
68
+ super.visitVariableUse(vertex);
69
+ this.onVariableUse({ vertex });
70
+ }
71
+ /**
72
+ * See {@link DataflowAwareCfgGuidedVisitor#visitVariableDefinition} for the base implementation.
73
+ *
74
+ * This function is called for every variable definition in the program and dispatches the appropriate event.
75
+ * You probably do not have to overwrite it and just use {@link SemanticCfgGuidedVisitor#onVariableDefinition|`onVariableDefinition`} instead.
76
+ *
77
+ * @protected
78
+ */
79
+ visitVariableDefinition(vertex) {
80
+ super.visitVariableDefinition(vertex);
81
+ this.onVariableDefinition({ vertex });
82
+ }
83
+ /**
84
+ * See {@link DataflowAwareCfgGuidedVisitor#visitFunctionDefinition} for the base implementation.
85
+ *
86
+ * This function is called for every function definition in the program and dispatches the appropriate event.
87
+ * You probably do not have to overwrite it and just use {@link SemanticCfgGuidedVisitor#onFunctionDefinition|`onFunctionDefinition`} instead.
88
+ *
89
+ * @protected
90
+ */
91
+ visitFunctionDefinition(vertex) {
92
+ super.visitFunctionDefinition(vertex);
93
+ this.onFunctionDefinition({ vertex });
94
+ }
95
+ /**
96
+ * See {@link DataflowAwareCfgGuidedVisitor#visitFunctionCall} for the base implementation.
97
+ *
98
+ * This function is called for every function call in the program and dispatches the appropriate event.
99
+ * You probably do not have to overwrite it and just use {@link SemanticCfgGuidedVisitor#onUnnamedCall|`onUnnamedCall`} for anonymous calls,
100
+ * or {@link SemanticCfgGuidedVisitor#onDispatchFunctionCallOrigins|`onDispatchFunctionCallOrigins`} for named calls (or just overwrite
101
+ * the events you are interested in directly).
102
+ *
103
+ * @protected
104
+ */
105
+ visitFunctionCall(vertex) {
106
+ super.visitFunctionCall(vertex);
107
+ if (vertex.origin === 'unnamed') {
108
+ this.onUnnamedCall({ vertex });
109
+ }
110
+ else {
111
+ this.onDispatchFunctionCallOrigins(vertex, vertex.origin);
112
+ }
113
+ }
114
+ /**
115
+ * See {@link DataflowAwareCfgGuidedVisitor#visitUnknown} for the base implementation.
116
+ * This function is called for every unknown vertex in the program.
117
+ * It dispatches the appropriate event based on the type of the vertex.
118
+ * In case you have to overwrite this function please make sure to still call this implementation to get a correctly working {@link SemanticCfgGuidedVisitor#onProgram|`onProgram`}.
119
+ *
120
+ * @protected
121
+ */
122
+ visitUnknown(vertex) {
123
+ super.visitUnknown(vertex);
124
+ const ast = this.getNormalizedAst(vertex.id);
125
+ if (ast && ast.type === type_1.RType.ExpressionList && ast.info.parent === undefined) {
126
+ this.onProgram(ast);
127
+ }
128
+ }
129
+ /**
130
+ * Given a function call that has multiple targets (e.g., two potential built-in definitions).
131
+ * This function is responsible for calling {@link onDispatchFunctionCallOrigin} for each of the origins,
132
+ * and aggregating their results (which is just additive by default).
133
+ * If you want to change the behavior in case of multiple potential function definition targets, simply overwrite this function
134
+ * with the logic you desire.
135
+ *
136
+ * @protected
137
+ */
138
+ onDispatchFunctionCallOrigins(call, origins) {
139
+ for (const origin of origins) {
140
+ this.onDispatchFunctionCallOrigin(call, origin);
141
+ }
142
+ }
143
+ /**
144
+ * This function is responsible for dispatching the appropriate event
145
+ * based on a given dataflow vertex. The default serves as a backend
146
+ * for the event functions, but you may overwrite and extend this function at will.
147
+ *
148
+ * @see {@link onDispatchFunctionCallOrigins} for the aggregation in case the function call target is ambiguous.
149
+ *
150
+ * @protected
151
+ */
152
+ onDispatchFunctionCallOrigin(call, origin) {
153
+ switch (origin) {
154
+ case 'builtin:eval':
155
+ return this.onEvalFunctionCall({ call });
156
+ case 'builtin:apply':
157
+ return this.onApplyFunctionCall({ call });
158
+ case 'builtin:expression-list':
159
+ return this.onExpressionList({ call });
160
+ case 'builtin:source':
161
+ return this.onSourceCall({ call });
162
+ case 'builtin:access':
163
+ return this.onAccessCall({ call });
164
+ case 'builtin:if-then-else':
165
+ return this.onIfThenElseCall({ call, condition: call.args[0], then: call.args[1], else: call.args[2] });
166
+ case 'builtin:get':
167
+ return this.onGetCall({ call });
168
+ case 'builtin:rm':
169
+ return this.onRmCall({ call });
170
+ case 'builtin:list':
171
+ return this.onListCall({ call });
172
+ case 'builtin:vector':
173
+ return this.onVectorCall({ call });
174
+ case 'table:assign':
175
+ case 'builtin:assignment': {
176
+ const outgoing = this.config.dataflow.graph.outgoingEdges(call.id);
177
+ if (outgoing) {
178
+ const target = [...outgoing.entries()].filter(([, e]) => (0, edge_1.edgeIncludesType)(e.types, edge_1.EdgeType.Returns));
179
+ if (target.length === 1) {
180
+ const targetOut = this.config.dataflow.graph.outgoingEdges(target[0][0]);
181
+ if (targetOut) {
182
+ const source = [...targetOut.entries()].filter(([t, e]) => (0, edge_1.edgeIncludesType)(e.types, edge_1.EdgeType.DefinedBy) && t !== call.id);
183
+ if (source.length === 1) {
184
+ return this.onAssignmentCall({ call, target: target[0][0], source: source[0][0] });
185
+ }
186
+ }
187
+ }
188
+ }
189
+ return this.onAssignmentCall({ call, target: undefined, source: undefined });
190
+ }
191
+ case 'builtin:special-bin-op':
192
+ return this.onSpecialBinaryOpCall({ call });
193
+ case 'builtin:pipe':
194
+ return this.onPipeCall({ call });
195
+ case 'builtin:quote':
196
+ return this.onQuoteCall({ call });
197
+ case 'builtin:for-loop':
198
+ return this.onForLoopCall({ call, variable: call.args[0], vector: call.args[1], body: call.args[2] });
199
+ case 'builtin:repeat-loop':
200
+ return this.onRepeatLoopCall({ call, body: call.args[0] });
201
+ case 'builtin:while-loop':
202
+ return this.onWhileLoopCall({ call, condition: call.args[0], body: call.args[1] });
203
+ case 'builtin:replacement': {
204
+ const outgoing = this.config.dataflow.graph.outgoingEdges(call.id);
205
+ if (outgoing) {
206
+ const target = [...outgoing.entries()].filter(([, e]) => (0, edge_1.edgeIncludesType)(e.types, edge_1.EdgeType.Returns));
207
+ if (target.length === 1) {
208
+ const targetOut = this.config.dataflow.graph.outgoingEdges(target[0][0]);
209
+ if (targetOut) {
210
+ const source = [...targetOut.entries()].filter(([t, e]) => (0, edge_1.edgeIncludesType)(e.types, edge_1.EdgeType.DefinedBy) && t !== call.id);
211
+ if (source.length === 1) {
212
+ return this.onReplacementCall({ call, target: target[0][0], source: source[0][0] });
213
+ }
214
+ }
215
+ }
216
+ }
217
+ return this.onReplacementCall({ call, target: undefined, source: undefined });
218
+ }
219
+ case 'builtin:library':
220
+ return this.onLibraryCall({ call });
221
+ case 'builtin:default':
222
+ default:
223
+ return this.onDefaultFunctionCall({ call });
224
+ }
225
+ }
226
+ onProgram(_data) {
227
+ }
228
+ /**
229
+ * A helper function to request the {@link getOriginInDfg|origins} of the given node.
230
+ */
231
+ getOrigins(id) {
232
+ return (0, dfg_get_origin_1.getOriginInDfg)(this.config.dataflow.graph, id);
233
+ }
234
+ /** Called for every occurrence of a `NULL` in the program. */
235
+ onNullConstant(_data) { }
236
+ /**
237
+ * Called for every constant string value in the program.
238
+ *
239
+ * For example, `"Hello World"` in `print("Hello World")`.
240
+ */
241
+ onStringConstant(_data) { }
242
+ /**
243
+ * Called for every constant number value in the program.
244
+ *
245
+ * For example, `42` in `print(42)`.
246
+ */
247
+ onNumberConstant(_data) { }
248
+ /**
249
+ * Called for every constant logical value in the program.
250
+ *
251
+ * For example, `TRUE` in `if(TRUE) { ... }`.
252
+ */
253
+ onLogicalConstant(_data) { }
254
+ /**
255
+ * Called for every variable that is read within the program.
256
+ * You can use {@link getOrigins} to get the origins of the variable.
257
+ *
258
+ * For example, `x` in `print(x)`.
259
+ */
260
+ onVariableUse(_data) { }
261
+ /**
262
+ * Called for every variable that is written within the program.
263
+ * You can use {@link getOrigins} to get the origins of the variable.
264
+ *
265
+ * For example, `x` in `x <- 42` or `x` in `assign("x", 42)`.
266
+ * See {@link SemanticCfgGuidedVisitor#onAssignmentCall} for the assignment call. This event handler also provides you with information on the source.
267
+ */
268
+ onVariableDefinition(_data) { }
269
+ /**
270
+ * Called for every anonymous function definition.
271
+ *
272
+ * For example, `function(x) { x + 1 }` in `lapply(1:10, function(x) { x + 1 })`.
273
+ */
274
+ onFunctionDefinition(_data) { }
275
+ /**
276
+ * This event triggers for every anonymous call within the program.
277
+ *
278
+ * For example, `(function(x) { x + 1 })(42)` or the second call in `a()()`.
279
+ *
280
+ * This is separate from {@link SemanticCfgGuidedVisitor#onDefaultFunctionCall|`onDefaultFunctionCall`} which is used for named function calls that do not trigger any of these events.
281
+ * The main differentiation for these calls is that you may not infer their semantics from any name alone and probably _have_
282
+ * to rely on {@link SemanticCfgGuidedVisitor#getOrigins|`getOrigins`} to get more information.
283
+ *
284
+ * @protected
285
+ */
286
+ onUnnamedCall(_data) { }
287
+ /**
288
+ * This event triggers for every function call that is not handled by a specific overload,
289
+ * and hence may be a function that targets a user-defined function. In a way, these are functions that are named,
290
+ * but flowR does not specifically care about them (currently) wrt. to their dataflow impact.
291
+ *
292
+ * Use {@link SemanticCfgGuidedVisitor#getOrigins|`getOrigins`} to get the origins of the call.
293
+ *
294
+ * For example, this triggers for `foo(x)` in
295
+ *
296
+ * ```r
297
+ * foo <- function(x) { x + 1 }
298
+ * foo(x)
299
+ * ```
300
+ *
301
+ * This explicitly will not trigger for scenarios in which the function has no name (i.e., if it is anonymous).
302
+ * For such cases, you may rely on the {@link SemanticCfgGuidedVisitor#onUnnamedCall|`onUnnamedCall`} event.
303
+ * The main reason for this separation is part of flowR's handling of these functions, as anonmyous calls cannot be resolved using the active environment.
304
+ *
305
+ * @protected
306
+ */
307
+ onDefaultFunctionCall(_data) { }
308
+ /**
309
+ * This event triggers for every call to the `eval` function.
310
+ *
311
+ * For example, `eval` in `eval(parse(text = "x + 1"))`.
312
+ *
313
+ * More specifically, this relates to the corresponding {@link BuiltInProcessorMapper} handler.
314
+ *
315
+ * @protected
316
+ */
317
+ onEvalFunctionCall(_data) { }
318
+ /**
319
+ * This event triggers for every call to any of the `*apply` functions.
320
+ *
321
+ * For example, `lapply` in `lapply(1:10, function(x) { x + 1 })`.
322
+ *
323
+ * More specifically, this relates to the corresponding {@link BuiltInProcessorMapper} handler.
324
+ *
325
+ * @protected
326
+ */
327
+ onApplyFunctionCall(_data) { }
328
+ /**
329
+ * This event triggers for every expression list - implicit or explicit, _but_ not for the root program (see {@link SemanticCfgGuidedVisitor#onProgram|`onProgram`} for that).
330
+ *
331
+ * For example, this triggers for the expression list created by `{` and `}` in `ìf (TRUE) { x <- 1; y <- 2; }`. But also for the implicit
332
+ * expression list `x <- x + 1` in `for(x in 1:10) x <- x + 1`.
333
+ *
334
+ * @protected
335
+ */
336
+ onExpressionList(_data) { }
337
+ /**
338
+ * This event triggers for every call to the `source` function.
339
+ *
340
+ * For example, `source` in `source("script.R")`.
341
+ *
342
+ * By default, this does not provide the resolved source file. Yet you can access the {@link DataflowGraph} to ask for sourced files.
343
+ *
344
+ * More specifically, this relates to the corresponding {@link BuiltInProcessorMapper} handler.
345
+ *
346
+ * @protected
347
+ */
348
+ onSourceCall(_data) { }
349
+ /**
350
+ * This event triggers for every subsetting call, i.e., for every call to `[[`, `[`, or `$`.
351
+ *
352
+ * @protected
353
+ */
354
+ onAccessCall(_data) {
355
+ }
356
+ /**
357
+ * This event triggers for every call to the `if` function, which is used to implement the `if-then-else` control flow.
358
+ *
359
+ * @protected
360
+ */
361
+ onIfThenElseCall(_data) {
362
+ }
363
+ /**
364
+ * This event triggers for every call to the `get` function, which is used to access variables in the global environment.
365
+ *
366
+ * For example, `get` in `get("x")`.
367
+ *
368
+ * Please be aware, that with flowR resolving the `get` during the dataflow analysis,
369
+ * this may very well trigger a {@link SemanticCfgGuidedVisitor#onVariableUse|`onVariableUse`} event as well.
370
+ *
371
+ * @protected
372
+ */
373
+ onGetCall(_data) { }
374
+ /**
375
+ * This event triggers for every call to the `rm` function, which is used to remove variables from the environment.
376
+ *
377
+ * For example, `rm` in `rm(x)`.
378
+ *
379
+ * @protected
380
+ */
381
+ onRmCall(_data) { }
382
+ /**
383
+ * This event triggers for every call to a function which loads a library.
384
+ *
385
+ * For example, `library` in `library(dplyr)`.
386
+ *
387
+ * More specifically, this relates to the corresponding {@link BuiltInProcessorMapper} handler.
388
+ *
389
+ * @protected
390
+ */
391
+ onLibraryCall(_data) { }
392
+ /**
393
+ * This event triggers for every assignment call, i.e., for every call to `<-` or `=` that assigns a value to a variable.
394
+ *
395
+ * For example, this triggers for `<-` in `x <- 42` or `assign` in `assign("x", 42)`.
396
+ * This also triggers for the `data.table` assign `:=` active within subsetting calls, e.g., `DT[, x := 42]`.
397
+ *
398
+ * Please be aware that replacements (e.g. assignments with a function call on the target side) like `names(x) <- 3` are subject to {@link SemanticCfgGuidedVisitor#onReplacementCall|`onReplacementCall`} instead.
399
+ * @protected
400
+ */
401
+ onAssignmentCall(_data) { }
402
+ /**
403
+ * This event triggers for every call to a special binary operator, i.e., every binary function call that starts and ends with a `%` sign.
404
+ *
405
+ * For example, this triggers for`%in%` in `x %in% y`.
406
+ *
407
+ * More specifically, this relates to the corresponding {@link BuiltInProcessorMapper} handler.
408
+ *
409
+ * @protected
410
+ */
411
+ onSpecialBinaryOpCall(_data) { }
412
+ /**
413
+ * This event triggers for every call to R's pipe operator, i.e., for every call to `|>`.
414
+ *
415
+ * @protected
416
+ */
417
+ onPipeCall(_data) { }
418
+ /**
419
+ * This event triggers for every call to the `quote` function, which is used to quote expressions.
420
+ *
421
+ * For example, `quote` in `quote(x + 1)`.
422
+ *
423
+ * More specifically, this relates to the corresponding {@link BuiltInProcessorMapper} handler.
424
+ *
425
+ * @protected
426
+ */
427
+ onQuoteCall(_data) { }
428
+ /**
429
+ * This event triggers for every call to the `for` loop function, which is used to implement the `for` loop control flow.
430
+ *
431
+ * For example, this triggers for `for` in `for(i in 1:10) { print(i) }`.
432
+ *
433
+ * More specifically, this relates to the corresponding {@link BuiltInProcessorMapper} handler.
434
+ *
435
+ * @protected
436
+ */
437
+ onForLoopCall(_data) { }
438
+ /**
439
+ * This event triggers for every call to the `while` loop function, which is used to implement the `while` loop control flow.
440
+ *
441
+ * For example, this triggers for `while` in `while(i < 10) { i <- i + 1 }`.
442
+ *
443
+ * More specifically, this relates to the corresponding {@link BuiltInProcessorMapper} handler.
444
+ *
445
+ * @protected
446
+ */
447
+ onWhileLoopCall(_data) { }
448
+ /**
449
+ * This event triggers for every call to the `repeat` loop function, which is used to implement the `repeat` loop control flow.
450
+ *
451
+ * For example, this triggers for `repeat` in `repeat { i <- i + 1; if(i >= 10) break }`.
452
+ *
453
+ * More specifically, this relates to the corresponding {@link BuiltInProcessorMapper} handler.
454
+ *
455
+ * @protected
456
+ */
457
+ onRepeatLoopCall(_data) { }
458
+ /**
459
+ * This event triggers for every call to a function that replaces a value in a container, such as `names(x) <- 3`.
460
+ *
461
+ * This is different from {@link SemanticCfgGuidedVisitor#onAssignmentCall|`onAssignmentCall`} in that it does not assign a value to a variable,
462
+ * but rather replaces a value in a container.
463
+ *
464
+ * For example, this triggers for `names` in `names(x) <- 3`, but not for `x <- 3`.
465
+ *
466
+ * More specifically, this relates to the corresponding {@link BuiltInProcessorMapper} handler.
467
+ * @protected
468
+ */
469
+ onReplacementCall(_data) { }
470
+ /**
471
+ * This event triggers for every call that (to the knowledge of flowr) constructs a (new) list.
472
+ *
473
+ * For example, this triggers for `list` in `list(1, 2, 3)`.
474
+ *
475
+ * More specifically, this relates to the corresponding {@link BuiltInProcessorMapper} handler.
476
+ *
477
+ * @protected
478
+ */
479
+ onListCall(_data) { }
480
+ /**
481
+ * This event triggers for every call that (to the knowledge of flowr) constructs a (new) vector.
482
+ *
483
+ * For example, this triggers for `c` in `c(1, 2, 3)`.
484
+ *
485
+ * More specifically, this relates to the corresponding {@link BuiltInProcessorMapper} handler.
486
+ *
487
+ * @protected
488
+ */
489
+ onVectorCall(_data) { }
490
+ }
491
+ exports.SemanticCfgGuidedVisitor = SemanticCfgGuidedVisitor;
492
+ //# sourceMappingURL=semantic-cfg-guided-visitor.js.map
@@ -0,0 +1,25 @@
1
+ import type { ControlFlowGraph } from './control-flow-graph';
2
+ import type { NodeId } from '../r-bridge/lang-4.x/ast/model/processing/node-id';
3
+ export type SimpleCfgVisitor = (graph: ControlFlowGraph, nodes: readonly NodeId[], visitor: (node: NodeId) => boolean | void) => void;
4
+ /**
5
+ * Visit all nodes reachable from the start node in the control flow graph, traversing the dependencies but ignoring cycles.
6
+ * @param graph - The control flow graph.
7
+ * @param startNodes - The nodes to start the traversal from.
8
+ * @param visitor - The visitor function to call for each node, if you return true the traversal from this node will be stopped.
9
+ *
10
+ * This function is of type {@link SimpleCfgVisitor}.
11
+ *
12
+ * @see {@link visitCfgInOrder} for a traversal in order
13
+ */
14
+ export declare function visitCfgInReverseOrder(graph: ControlFlowGraph, startNodes: readonly NodeId[], visitor: (node: NodeId) => boolean | void): void;
15
+ /**
16
+ * Visit all nodes reachable from the start node in the control flow graph, traversing the dependencies in execution order but ignoring cycles.
17
+ * @param graph - The control flow graph.
18
+ * @param startNodes - The nodes to start the traversal from.
19
+ * @param visitor - The visitor function to call for each node, if you return true the traversal from this node will be stopped.
20
+ *
21
+ * This function is of type {@link SimpleCfgVisitor}.
22
+ *
23
+ * @see {@link visitCfgInReverseOrder} for a traversal in reversed order
24
+ */
25
+ export declare function visitCfgInOrder(graph: ControlFlowGraph, startNodes: readonly NodeId[], visitor: (node: NodeId) => boolean | void): void;
@@ -0,0 +1,80 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.visitCfgInReverseOrder = visitCfgInReverseOrder;
4
+ exports.visitCfgInOrder = visitCfgInOrder;
5
+ const control_flow_graph_1 = require("./control-flow-graph");
6
+ /**
7
+ * Visit all nodes reachable from the start node in the control flow graph, traversing the dependencies but ignoring cycles.
8
+ * @param graph - The control flow graph.
9
+ * @param startNodes - The nodes to start the traversal from.
10
+ * @param visitor - The visitor function to call for each node, if you return true the traversal from this node will be stopped.
11
+ *
12
+ * This function is of type {@link SimpleCfgVisitor}.
13
+ *
14
+ * @see {@link visitCfgInOrder} for a traversal in order
15
+ */
16
+ function visitCfgInReverseOrder(graph, startNodes,
17
+ // eslint-disable-next-line @typescript-eslint/no-invalid-void-type -- void is used to indicate that the return value is ignored/we never stop
18
+ visitor) {
19
+ const visited = new Set();
20
+ let queue = [...startNodes];
21
+ const hasBb = graph.mayHaveBasicBlocks();
22
+ while (queue.length > 0) {
23
+ const current = queue.pop();
24
+ if (visited.has(current)) {
25
+ continue;
26
+ }
27
+ visited.add(current);
28
+ if (visitor(current)) {
29
+ continue;
30
+ }
31
+ else if (hasBb) {
32
+ const get = graph.getVertex(current);
33
+ if (get?.type === control_flow_graph_1.CfgVertexType.Block) {
34
+ queue = queue.concat(get.elems.toReversed().map(e => e.id));
35
+ }
36
+ }
37
+ const incoming = graph.outgoingEdges(current) ?? [];
38
+ for (const [from] of incoming) {
39
+ queue.push(from);
40
+ }
41
+ }
42
+ }
43
+ /**
44
+ * Visit all nodes reachable from the start node in the control flow graph, traversing the dependencies in execution order but ignoring cycles.
45
+ * @param graph - The control flow graph.
46
+ * @param startNodes - The nodes to start the traversal from.
47
+ * @param visitor - The visitor function to call for each node, if you return true the traversal from this node will be stopped.
48
+ *
49
+ * This function is of type {@link SimpleCfgVisitor}.
50
+ *
51
+ * @see {@link visitCfgInReverseOrder} for a traversal in reversed order
52
+ */
53
+ function visitCfgInOrder(graph, startNodes,
54
+ // eslint-disable-next-line @typescript-eslint/no-invalid-void-type -- void is used to indicate that the return value is ignored/we never stop
55
+ visitor) {
56
+ const visited = new Set();
57
+ let queue = startNodes.slice();
58
+ const hasBb = graph.mayHaveBasicBlocks();
59
+ while (queue.length > 0) {
60
+ const current = queue.shift();
61
+ if (visited.has(current)) {
62
+ continue;
63
+ }
64
+ visited.add(current);
65
+ if (visitor(current)) {
66
+ continue;
67
+ }
68
+ else if (hasBb) {
69
+ const get = graph.getVertex(current);
70
+ if (get?.type === control_flow_graph_1.CfgVertexType.Block) {
71
+ queue = queue.concat(get.elems.map(e => e.id));
72
+ }
73
+ }
74
+ const outgoing = graph.ingoingEdges(current) ?? [];
75
+ for (const [to] of outgoing) {
76
+ queue.push(to);
77
+ }
78
+ }
79
+ }
80
+ //# sourceMappingURL=simple-visitor.js.map