@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
@@ -4,66 +4,66 @@ exports.processReplacementFunction = processReplacementFunction;
4
4
  const info_1 = require("../../../../../info");
5
5
  const known_call_handling_1 = require("../known-call-handling");
6
6
  const log_1 = require("../../../../../../util/log");
7
- const built_in_assignment_1 = require("./built-in-assignment");
8
7
  const common_1 = require("../common");
9
- const assert_1 = require("../../../../../../util/assert");
10
8
  const r_function_call_1 = require("../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-function-call");
11
9
  const logger_1 = require("../../../../../logger");
12
10
  const vertex_1 = require("../../../../../graph/vertex");
13
11
  const graph_1 = require("../../../../../graph/graph");
14
12
  const edge_1 = require("../../../../../graph/edge");
15
- const dfg_1 = require("../../../../../../util/mermaid/dfg");
16
13
  const type_1 = require("../../../../../../r-bridge/lang-4.x/ast/model/type");
17
- const list_access_1 = require("../../../../../../util/list-access");
14
+ const containers_1 = require("../../../../../../util/containers");
18
15
  const config_1 = require("../../../../../../config");
16
+ const unpack_argument_1 = require("../argument/unpack-argument");
17
+ const built_in_access_1 = require("./built-in-access");
18
+ const built_in_1 = require("../../../../../environments/built-in");
19
+ const identifier_1 = require("../../../../../environments/identifier");
19
20
  function processReplacementFunction(name,
20
21
  /** The last one has to be the value */
21
22
  args, rootId, data, config) {
22
23
  if (args.length < 2) {
23
24
  logger_1.dataflowLogger.warn(`Replacement ${name.content} has less than 2 arguments, skipping`);
24
- return (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data }).information;
25
+ return (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data, origin: 'default' }).information;
25
26
  }
26
27
  /* we only get here if <-, <<-, ... or whatever is part of the replacement is not overwritten */
27
28
  (0, log_1.expensiveTrace)(logger_1.dataflowLogger, () => `Replacement ${name.content} with ${JSON.stringify(args)}, processing`);
28
- let indices = undefined;
29
- if (name.content === '$<-' && (0, config_1.getConfig)().solver.pointerTracking) {
30
- const nonEmptyArgs = args.filter(arg => arg !== r_function_call_1.EmptyArgument);
31
- const accessedArg = nonEmptyArgs.find(arg => arg.info.role === "accessed" /* RoleInParent.Accessed */);
32
- const accessArg = nonEmptyArgs.find(arg => arg.info.role === "index-access" /* RoleInParent.IndexAccess */);
33
- if (accessArg !== undefined && accessedArg != undefined) {
34
- const leafIndex = { lexeme: accessArg.lexeme, nodeId: accessedArg.info.parent ?? '' };
35
- const accessIndices = {
36
- indices: [leafIndex],
37
- isContainer: false
38
- };
39
- // Check for nested access
40
- if (accessedArg.value?.type === type_1.RType.Access) {
41
- indices = (0, list_access_1.constructNestedAccess)(accessedArg.value, accessIndices);
42
- }
43
- else {
44
- // use access node as reference to get complete line in slice
45
- indices = [accessIndices];
46
- }
47
- }
29
+ let indices = config.activeIndices;
30
+ if ((0, config_1.getConfig)().solver.pointerTracking) {
31
+ indices ??= constructAccessedIndices(name.content, args);
48
32
  }
49
33
  /* we assign the first argument by the last for now and maybe mark as maybe!, we can keep the symbol as we now know we have an assignment */
50
- const res = (0, built_in_assignment_1.processAssignment)(name, [args[0], args[args.length - 1]], rootId, data, {
34
+ let res = built_in_1.BuiltInProcessorMapper['builtin:assignment'](name, [args[0], args[args.length - 1]], rootId, data, {
51
35
  superAssignment: config.assignmentOperator === '<<-',
52
36
  makeMaybe: indices !== undefined ? false : config.makeMaybe,
53
- indicesCollection: indices
37
+ indicesCollection: indices,
38
+ canBeReplacement: true
54
39
  });
40
+ const createdVert = res.graph.getVertex(rootId);
41
+ if (createdVert?.tag === vertex_1.VertexType.FunctionCall) {
42
+ createdVert.origin = ['builtin:replacement'];
43
+ }
44
+ const convertedArgs = config.readIndices ? args.slice(1, -1) : (0, built_in_access_1.symbolArgumentsToStrings)(args.slice(1, -1), 0);
55
45
  /* now, we soft-inject other arguments, so that calls like `x[y] <- 3` are linked correctly */
56
46
  const { callArgs } = (0, common_1.processAllArguments)({
57
47
  functionName: (0, info_1.initializeCleanDataflowInformation)(rootId, data),
58
- args: args.slice(1, -1),
48
+ args: convertedArgs,
59
49
  data,
60
50
  functionRootId: rootId,
61
51
  finalGraph: res.graph,
62
52
  forceArgs: config.forceArgs,
63
53
  });
64
- const fn = res.graph.getVertex(rootId, true);
65
- (0, assert_1.guard)(fn?.tag === vertex_1.VertexType.FunctionCall && fn.args.length === 2, () => `Function ${rootId} not found in graph or not 2-arg fn-call (${JSON.stringify(fn)}) ${(0, dfg_1.graphToMermaidUrl)(res.graph)}`);
66
- fn.args = [fn.args[0], ...callArgs, fn.args[1]];
54
+ (0, common_1.patchFunctionCall)({
55
+ nextGraph: res.graph,
56
+ data,
57
+ rootId,
58
+ name,
59
+ argumentProcessResult: args.map(a => a === r_function_call_1.EmptyArgument ? undefined : { entryPoint: (0, unpack_argument_1.unpackArgument)(a)?.info.id }),
60
+ origin: 'builtin:replacement',
61
+ link: config.assignRootId ? { origin: [config.assignRootId] } : undefined
62
+ });
63
+ const firstArg = (0, unpack_argument_1.unpackArgument)(args[0])?.info.id;
64
+ if (firstArg) {
65
+ res.graph.addEdge(firstArg, rootId, edge_1.EdgeType.DefinedBy | edge_1.EdgeType.Reads);
66
+ }
67
67
  /* a replacement reads all of its call args as well, at least as far as I am aware of */
68
68
  for (const arg of callArgs) {
69
69
  const ref = (0, graph_1.getReferenceOfArgument)(arg);
@@ -71,6 +71,75 @@ args, rootId, data, config) {
71
71
  res.graph.addEdge(rootId, ref, edge_1.EdgeType.Reads);
72
72
  }
73
73
  }
74
+ const fa = (0, unpack_argument_1.unpackArgument)(args[0]);
75
+ if (!(0, config_1.getConfig)().solver.pointerTracking && fa) {
76
+ res = {
77
+ ...res,
78
+ in: [...res.in, { name: fa.lexeme, type: identifier_1.ReferenceType.Variable, nodeId: fa.info.id, controlDependencies: data.controlDependencies }]
79
+ };
80
+ }
74
81
  return res;
75
82
  }
83
+ /**
84
+ * Constructs accessed indices of replacement function recursively.
85
+ *
86
+ * Example:
87
+ * ```r
88
+ * a$b <- 1
89
+ * # results in index with lexeme b as identifier
90
+ *
91
+ * a[[1]]$b
92
+ * # results in index with index 1 as identifier with a sub-index with lexeme b as identifier
93
+ * ```
94
+ *
95
+ * @param operation - Operation of replacement function e.g. '$\<-', '[\<-', '[[\<-'
96
+ * @param args - Arguments of the replacement function
97
+ * @returns Accessed indices construct
98
+ */
99
+ function constructAccessedIndices(operation, args) {
100
+ const { accessedArg, accessArg } = (0, containers_1.getAccessOperands)(args);
101
+ if (accessedArg === undefined || accessArg?.value === undefined || !isSupportedOperation(operation, accessArg.value)) {
102
+ return undefined;
103
+ }
104
+ const constructIdentifier = getIdentifierBuilder(operation);
105
+ const leafIndex = {
106
+ identifier: constructIdentifier(accessArg),
107
+ nodeId: accessedArg.info.parent ?? ''
108
+ };
109
+ const accessIndices = {
110
+ indices: [leafIndex],
111
+ isContainer: false
112
+ };
113
+ // Check for nested access
114
+ let indicesCollection = undefined;
115
+ if (accessedArg.value?.type === type_1.RType.Access) {
116
+ indicesCollection = (0, containers_1.constructNestedAccess)(accessedArg.value, accessIndices, constructIdentifier);
117
+ }
118
+ else {
119
+ // use access node as reference to get complete line in slice
120
+ indicesCollection = [accessIndices];
121
+ }
122
+ return indicesCollection;
123
+ }
124
+ function isSupportedOperation(operation, value) {
125
+ const isNameBasedAccess = (operation === '$<-' || operation === '@<-') && value.type === type_1.RType.Symbol;
126
+ const isNumericalIndexBasedAccess = (operation === '[[<-' || operation === '[<-') && value.type === type_1.RType.Number;
127
+ return isNameBasedAccess || isNumericalIndexBasedAccess;
128
+ }
129
+ function getIdentifierBuilder(operation) {
130
+ if (operation === '$<-' || operation == '@<-') {
131
+ return (arg) => {
132
+ return {
133
+ index: undefined,
134
+ lexeme: arg.lexeme,
135
+ };
136
+ };
137
+ }
138
+ // [[<- and [<-
139
+ return (arg) => {
140
+ return {
141
+ index: Number(arg.lexeme),
142
+ };
143
+ };
144
+ }
76
145
  //# sourceMappingURL=built-in-replacement.js.map
@@ -0,0 +1,7 @@
1
+ import type { DataflowProcessorInformation } from '../../../../../processor';
2
+ import type { DataflowInformation } from '../../../../../info';
3
+ import type { ParentInformation } from '../../../../../../r-bridge/lang-4.x/ast/model/processing/decorate';
4
+ import type { RFunctionArgument } from '../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-function-call';
5
+ import type { RSymbol } from '../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-symbol';
6
+ import type { NodeId } from '../../../../../../r-bridge/lang-4.x/ast/model/processing/node-id';
7
+ export declare function processRm<OtherInfo>(name: RSymbol<OtherInfo & ParentInformation>, args: readonly RFunctionArgument<OtherInfo & ParentInformation>[], rootId: NodeId, data: DataflowProcessorInformation<OtherInfo & ParentInformation>): DataflowInformation;
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.processRm = processRm;
4
+ const known_call_handling_1 = require("../known-call-handling");
5
+ const r_function_call_1 = require("../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-function-call");
6
+ const logger_1 = require("../../../../../logger");
7
+ const remove_1 = require("../../../../../environments/remove");
8
+ const type_1 = require("../../../../../../r-bridge/lang-4.x/ast/model/type");
9
+ function processRm(name, args, rootId, data) {
10
+ if (args.length === 0) {
11
+ logger_1.dataflowLogger.warn('empty rm, skipping');
12
+ return (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data, origin: 'default' }).information;
13
+ }
14
+ const res = (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data, origin: 'builtin:rm' }).information;
15
+ const names = [];
16
+ for (const arg of args) {
17
+ if (arg === r_function_call_1.EmptyArgument) {
18
+ logger_1.dataflowLogger.warn('empty argument in rm, skipping');
19
+ continue;
20
+ }
21
+ const unpacked = arg.value;
22
+ if (unpacked === undefined || (unpacked.type !== type_1.RType.Symbol && unpacked.type !== type_1.RType.String)) {
23
+ logger_1.dataflowLogger.warn(`argument is not a symbol or string, skipping ${JSON.stringify(unpacked)}`);
24
+ }
25
+ else if (unpacked.type === type_1.RType.Symbol) {
26
+ names.push(unpacked.content);
27
+ }
28
+ else if (unpacked.type === type_1.RType.String) {
29
+ names.push(unpacked.content.str);
30
+ }
31
+ }
32
+ let env = res.environment;
33
+ for (const name of names) {
34
+ env = (0, remove_1.remove)(name, env);
35
+ }
36
+ return {
37
+ ...res,
38
+ environment: env
39
+ };
40
+ }
41
+ //# sourceMappingURL=built-in-rm.js.map
@@ -55,6 +55,14 @@ function platformDirname(p) {
55
55
  function returnPlatformPath(p) {
56
56
  return p.replaceAll(AnyPathSeparator, path_1.default.sep);
57
57
  }
58
+ function applyReplacements(path, replacements) {
59
+ const results = [];
60
+ for (const replacement of replacements) {
61
+ const newPath = Object.entries(replacement).reduce((acc, [key, value]) => acc.replace(new RegExp(key, 'g'), value), path);
62
+ results.push(newPath);
63
+ }
64
+ return results;
65
+ }
58
66
  /**
59
67
  * Tries to find sourced by a source request and returns the first path that exists
60
68
  * @param seed - the path originally requested in the `source` call
@@ -67,7 +75,7 @@ function findSource(seed, data) {
67
75
  ...(config?.searchPath ?? []),
68
76
  ...(inferWdFromScript(config?.inferWorkingDirectory ?? config_1.InferWorkingDirectory.No, data.referenceChain))
69
77
  ];
70
- const tryPaths = [seed];
78
+ let tryPaths = [seed];
71
79
  switch (config?.dropPaths ?? config_1.DropPathsOption.No) {
72
80
  case config_1.DropPathsOption.Once: {
73
81
  const first = platformBasename(seed);
@@ -77,6 +85,7 @@ function findSource(seed, data) {
77
85
  case config_1.DropPathsOption.All: {
78
86
  const paths = platformDirname(seed).split(AnyPathSeparator);
79
87
  const basename = platformBasename(seed);
88
+ tryPaths.push(basename);
80
89
  if (paths.length === 1 && paths[0] === '.') {
81
90
  break;
82
91
  }
@@ -89,6 +98,10 @@ function findSource(seed, data) {
89
98
  case config_1.DropPathsOption.No:
90
99
  break;
91
100
  }
101
+ if (config?.applyReplacements) {
102
+ const r = config.applyReplacements;
103
+ tryPaths = tryPaths.flatMap(t => applyReplacements(t, r));
104
+ }
92
105
  const found = [];
93
106
  for (const explore of [undefined, ...explorePaths]) {
94
107
  for (const tryPath of tryPaths) {
@@ -99,12 +112,18 @@ function findSource(seed, data) {
99
112
  }
100
113
  }
101
114
  }
102
- log_1.log.info(`Found sourced file ${JSON.stringify(seed)} at ${JSON.stringify(found)}`);
115
+ if (log_1.log.settings.minLevel >= 3 /* LogLevel.Info */) {
116
+ log_1.log.info(`Found sourced file ${JSON.stringify(seed)} at ${JSON.stringify(found)}`);
117
+ }
103
118
  return found;
104
119
  }
105
120
  function processSourceCall(name, args, rootId, data, config) {
121
+ if (args.length !== 1) {
122
+ logger_1.dataflowLogger.warn(`Expected exactly one argument for source currently, but got ${args.length} instead, skipping`);
123
+ return (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data, origin: 'default' }).information;
124
+ }
106
125
  const information = config.includeFunctionCall ?
107
- (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data }).information
126
+ (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data, origin: 'builtin:source' }).information
108
127
  : (0, info_1.initializeCleanDataflowInformation)(rootId, data);
109
128
  const sourceFileArgument = args[0];
110
129
  if (!config.forceFollow && (0, config_1.getConfig)().ignoreSourceCalls) {
@@ -135,12 +154,14 @@ function processSourceCall(name, args, rootId, data, config) {
135
154
  if (filepath !== undefined) {
136
155
  const request = sourceProvider.createRequest(filepath);
137
156
  // check if the sourced file has already been dataflow analyzed, and if so, skip it
138
- if (data.referenceChain.find(e => e.request === request.request && e.content === request.content)) {
139
- logger_1.dataflowLogger.warn(`Found loop in dataflow analysis for ${JSON.stringify(request)}: ${JSON.stringify(data.referenceChain)}, skipping further dataflow analysis`);
157
+ const limit = (0, config_1.getConfig)().solver.resolveSource?.repeatedSourceLimit ?? 0;
158
+ const findCount = data.referenceChain.filter(e => e.request === request.request && e.content === request.content).length;
159
+ if (findCount > limit) {
160
+ logger_1.dataflowLogger.warn(`Found cycle (>=${limit + 1}) in dataflow analysis for ${JSON.stringify(request)}: ${JSON.stringify(data.referenceChain)}, skipping further dataflow analysis`);
140
161
  information.graph.markIdForUnknownSideEffects(rootId);
141
162
  return information;
142
163
  }
143
- return sourceRequest(rootId, request, data, information, (0, decorate_1.sourcedDeterministicCountingIdGenerator)(path, name.location));
164
+ return sourceRequest(rootId, request, data, information, (0, decorate_1.sourcedDeterministicCountingIdGenerator)((findCount > 0 ? findCount + '::' : '') + path, name.location));
144
165
  }
145
166
  }
146
167
  (0, log_1.expensiveTrace)(logger_1.dataflowLogger, () => `Non-constant argument ${JSON.stringify(sourceFile)} for source is currently not supported, skipping`);
@@ -193,7 +214,13 @@ function sourceRequest(rootId, request, data, information, getId) {
193
214
  for (const [k, v] of normalized.idMap) {
194
215
  data.completeAst.idMap.set(k, v);
195
216
  }
196
- return newInformation;
217
+ return {
218
+ ...newInformation,
219
+ in: newInformation.in.concat(dataflow.in),
220
+ out: newInformation.out.concat(dataflow.out),
221
+ unknownReferences: newInformation.unknownReferences.concat(dataflow.unknownReferences),
222
+ exitPoints: dataflow.exitPoints
223
+ };
197
224
  }
198
225
  function standaloneSourceFile(inputRequest, data, uniqueSourceId, information) {
199
226
  const path = inputRequest.request === 'file' ? inputRequest.content : '-inline-';
@@ -210,6 +237,6 @@ function standaloneSourceFile(inputRequest, data, uniqueSourceId, information) {
210
237
  currentRequest: request,
211
238
  environment: information.environment,
212
239
  referenceChain: [...data.referenceChain, inputRequest]
213
- }, information, (0, decorate_1.deterministicPrefixIdGenerator)(path + '@' + uniqueSourceId));
240
+ }, information, (0, decorate_1.deterministicPrefixIdGenerator)(path + '::' + uniqueSourceId));
214
241
  }
215
242
  //# sourceMappingURL=built-in-source.js.map
@@ -6,11 +6,11 @@ const logger_1 = require("../../../../../logger");
6
6
  const edge_1 = require("../../../../../graph/edge");
7
7
  function processSpecialBinOp(name, args, rootId, data, config) {
8
8
  if (!config.lazy) {
9
- return (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data }).information;
9
+ return (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data, origin: 'builtin:special-bin-op' }).information;
10
10
  }
11
11
  else if (args.length != 2) {
12
12
  logger_1.dataflowLogger.warn(`Logical bin-op ${name.content} has something else than 2 arguments, skipping`);
13
- return (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data, forceArgs: config.forceArgs }).information;
13
+ return (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data, forceArgs: config.forceArgs, origin: 'default' }).information;
14
14
  }
15
15
  const { information, processedArguments } = (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data, forceArgs: config.forceArgs,
16
16
  patchData: (d, i) => {
@@ -18,7 +18,8 @@ function processSpecialBinOp(name, args, rootId, data, config) {
18
18
  return { ...d, controlDependencies: [...d.controlDependencies ?? [], { id: name.info.id, when: config.evalRhsWhen }] };
19
19
  }
20
20
  return d;
21
- }
21
+ },
22
+ origin: 'builtin:special-bin-op'
22
23
  });
23
24
  for (const arg of processedArguments) {
24
25
  if (arg) {
@@ -0,0 +1,15 @@
1
+ import type { RFunctionArgument } from '../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-function-call';
2
+ import type { RSymbol } from '../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-symbol';
3
+ import type { ParentInformation } from '../../../../../../r-bridge/lang-4.x/ast/model/processing/decorate';
4
+ import type { NodeId } from '../../../../../../r-bridge/lang-4.x/ast/model/processing/node-id';
5
+ import type { DataflowInformation } from '../../../../../info';
6
+ import type { DataflowProcessorInformation } from '../../../../../processor';
7
+ /**
8
+ * Process a vector call.
9
+ *
10
+ * Example:
11
+ * ```r
12
+ * c(1, 2, 3, 4)
13
+ * ```
14
+ */
15
+ export declare function processVector<OtherInfo>(name: RSymbol<OtherInfo & ParentInformation>, args: readonly RFunctionArgument<OtherInfo & ParentInformation>[], rootId: NodeId, data: DataflowProcessorInformation<OtherInfo & ParentInformation>): DataflowInformation;
@@ -0,0 +1,75 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.processVector = processVector;
4
+ const r_function_call_1 = require("../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-function-call");
5
+ const type_1 = require("../../../../../../r-bridge/lang-4.x/ast/model/type");
6
+ const known_call_handling_1 = require("../known-call-handling");
7
+ const config_1 = require("../../../../../../config");
8
+ const containers_1 = require("../../../../../../util/containers");
9
+ /**
10
+ * Process a vector call.
11
+ *
12
+ * Example:
13
+ * ```r
14
+ * c(1, 2, 3, 4)
15
+ * ```
16
+ */
17
+ function processVector(name, args, rootId, data) {
18
+ const fnCall = (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data, origin: 'builtin:vector' });
19
+ if (!(0, config_1.getConfig)().solver.pointerTracking) {
20
+ return fnCall.information;
21
+ }
22
+ let vectorArgs = [];
23
+ let argIndex = 1;
24
+ for (const arg of args) {
25
+ // Skip invalid argument types
26
+ if (arg === r_function_call_1.EmptyArgument || arg.type !== type_1.RType.Argument || arg.value === undefined) {
27
+ continue;
28
+ }
29
+ if (isPrimitive(arg.value.type)) {
30
+ vectorArgs.push({
31
+ identifier: { index: argIndex++ },
32
+ nodeId: arg.value.info.id,
33
+ });
34
+ }
35
+ else {
36
+ // Check whether argument value can be resolved
37
+ let indicesCollection;
38
+ if (arg.value.type === type_1.RType.Symbol) {
39
+ indicesCollection = (0, containers_1.resolveIndicesByName)(arg.value.lexeme, data.environment);
40
+ }
41
+ else {
42
+ // Check whether argument is nested container
43
+ indicesCollection = fnCall.information.graph.getVertex(arg.value.info.id)?.indicesCollection;
44
+ }
45
+ const flattenedIndices = indicesCollection?.flatMap(indices => indices.indices)
46
+ .map(index => {
47
+ return {
48
+ identifier: { index: argIndex++ },
49
+ nodeId: index.nodeId,
50
+ };
51
+ }) ?? [];
52
+ vectorArgs = vectorArgs.concat(flattenedIndices);
53
+ }
54
+ }
55
+ if ((0, config_1.isOverPointerAnalysisThreshold)(vectorArgs.length)) {
56
+ return fnCall.information;
57
+ }
58
+ const indices = {
59
+ indices: vectorArgs,
60
+ isContainer: true,
61
+ };
62
+ // Add resolved indices to vertex
63
+ const vertex = fnCall.information.graph.getVertex(rootId);
64
+ if (vertex) {
65
+ vertex.indicesCollection = [indices];
66
+ }
67
+ return fnCall.information;
68
+ }
69
+ /**
70
+ * Checks whether the passed type is primitive i.e. number, logical or string.
71
+ */
72
+ function isPrimitive(type) {
73
+ return type === type_1.RType.Number || type === type_1.RType.Logical || type === type_1.RType.String;
74
+ }
75
+ //# sourceMappingURL=built-in-vector.js.map
@@ -14,12 +14,12 @@ const identifier_1 = require("../../../../../environments/identifier");
14
14
  function processWhileLoop(name, args, rootId, data) {
15
15
  if (args.length !== 2 || args[1] === r_function_call_1.EmptyArgument) {
16
16
  logger_1.dataflowLogger.warn(`While-Loop ${name.content} does not have 2 arguments, skipping`);
17
- return (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data }).information;
17
+ return (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data, origin: 'default' }).information;
18
18
  }
19
19
  const unpackedArgs = args.map(e => (0, unpack_argument_1.unpackArgument)(e));
20
20
  if (unpackedArgs.some(assert_1.isUndefined)) {
21
21
  logger_1.dataflowLogger.warn(`While-Loop ${name.content} has empty arguments in ${JSON.stringify(args)}, skipping`);
22
- return (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data }).information;
22
+ return (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data, origin: 'default' }).information;
23
23
  }
24
24
  /* we inject the cf-dependency of the while-loop after the condition */
25
25
  const { information, processedArguments } = (0, known_call_handling_1.processKnownFunctionCall)({
@@ -33,7 +33,7 @@ function processWhileLoop(name, args, rootId, data) {
33
33
  return { ...d, controlDependencies: [...d.controlDependencies ?? [], { id: name.info.id, when: true }] };
34
34
  }
35
35
  return d;
36
- }
36
+ }, origin: 'builtin:while-loop'
37
37
  });
38
38
  const [condition, body] = processedArguments;
39
39
  (0, assert_1.guard)(condition !== undefined && body !== undefined, () => `While-Loop ${name.content} has no condition or body, impossible!`);
@@ -7,6 +7,7 @@ import type { DataflowGraph, FunctionArgument } from '../../../../graph/graph';
7
7
  import type { NodeId } from '../../../../../r-bridge/lang-4.x/ast/model/processing/node-id';
8
8
  import type { REnvironmentInformation } from '../../../../environments/environment';
9
9
  import type { IdentifierReference } from '../../../../environments/identifier';
10
+ import type { DataflowGraphVertexAstLink, FunctionOriginInformation } from '../../../../graph/vertex';
10
11
  import type { RSymbol } from '../../../../../r-bridge/lang-4.x/ast/model/nodes/r-symbol';
11
12
  export interface ForceArguments {
12
13
  /** which of the arguments should be forced? this may be all, e.g., if the function itself is unknown on encounter */
@@ -34,6 +35,8 @@ export interface PatchFunctionCallInput<OtherInfo> {
34
35
  readonly rootId: NodeId;
35
36
  readonly name: RSymbol<OtherInfo & ParentInformation>;
36
37
  readonly data: DataflowProcessorInformation<OtherInfo & ParentInformation>;
37
- readonly argumentProcessResult: readonly (DataflowInformation | undefined)[];
38
+ readonly argumentProcessResult: readonly (Pick<DataflowInformation, 'entryPoint'> | undefined)[];
39
+ readonly origin: FunctionOriginInformation;
40
+ readonly link?: DataflowGraphVertexAstLink;
38
41
  }
39
- export declare function patchFunctionCall<OtherInfo>({ nextGraph, rootId, name, data, argumentProcessResult }: PatchFunctionCallInput<OtherInfo>): void;
42
+ export declare function patchFunctionCall<OtherInfo>({ nextGraph, rootId, name, data, argumentProcessResult, origin, link }: PatchFunctionCallInput<OtherInfo>): void;
@@ -64,9 +64,12 @@ function processAllArguments({ functionName, args, data, finalGraph, functionRoo
64
64
  }
65
65
  processedArguments.push(processed);
66
66
  finalEnv = (0, overwrite_1.overwriteEnvironment)(finalEnv, processed.environment);
67
+ finalGraph.mergeWith(processed.graph);
67
68
  // resolve reads within argument, we resolve before adding the `processed.environment` to avoid cyclic dependencies
68
69
  for (const ingoing of [...processed.in, ...processed.unknownReferences]) {
69
- const tryToResolve = ingoing.name ? (0, resolve_by_name_1.resolveByName)(ingoing.name, argEnv, identifier_1.ReferenceType.Unknown) : undefined;
70
+ // check if it is called directly
71
+ const vtx = finalGraph.getVertex(ingoing.nodeId);
72
+ const tryToResolve = ingoing.name ? (0, resolve_by_name_1.resolveByName)(ingoing.name, argEnv, vtx?.tag === vertex_1.VertexType.FunctionCall ? identifier_1.ReferenceType.Function : identifier_1.ReferenceType.Unknown) : undefined;
70
73
  if (tryToResolve === undefined) {
71
74
  remainingReadInArgs.push(ingoing);
72
75
  }
@@ -74,7 +77,7 @@ function processAllArguments({ functionName, args, data, finalGraph, functionRoo
74
77
  /* maybe all targets are not definitely of the current scope and should be still kept */
75
78
  let assumeItMayHaveAHigherTarget = true;
76
79
  for (const resolved of tryToResolve) {
77
- if ((0, info_1.happensInEveryBranch)(resolved.controlDependencies)) {
80
+ if ((0, info_1.happensInEveryBranch)(resolved.controlDependencies) && !(0, identifier_1.isReferenceType)(resolved.type, identifier_1.ReferenceType.BuiltInFunction | identifier_1.ReferenceType.BuiltInConstant)) {
78
81
  assumeItMayHaveAHigherTarget = false;
79
82
  }
80
83
  // When only a single index is referenced, we don't need to reference the whole object
@@ -90,7 +93,6 @@ function processAllArguments({ functionName, args, data, finalGraph, functionRoo
90
93
  }
91
94
  }
92
95
  argEnv = (0, overwrite_1.overwriteEnvironment)(argEnv, processed.environment);
93
- finalGraph.mergeWith(processed.graph);
94
96
  if (arg.type !== type_1.RType.Argument || !arg.name) {
95
97
  callArgs.push({ nodeId: processed.entryPoint, controlDependencies: undefined, type: identifier_1.ReferenceType.Argument });
96
98
  }
@@ -101,7 +103,7 @@ function processAllArguments({ functionName, args, data, finalGraph, functionRoo
101
103
  }
102
104
  return { finalEnv, callArgs, remainingReadInArgs, processedArguments };
103
105
  }
104
- function patchFunctionCall({ nextGraph, rootId, name, data, argumentProcessResult }) {
106
+ function patchFunctionCall({ nextGraph, rootId, name, data, argumentProcessResult, origin, link }) {
105
107
  nextGraph.addVertex({
106
108
  tag: vertex_1.VertexType.FunctionCall,
107
109
  id: rootId,
@@ -111,7 +113,9 @@ function patchFunctionCall({ nextGraph, rootId, name, data, argumentProcessResul
111
113
  onlyBuiltin: false,
112
114
  cds: data.controlDependencies,
113
115
  args: argumentProcessResult.map(arg => arg === undefined ? r_function_call_1.EmptyArgument : { nodeId: arg.entryPoint, controlDependencies: undefined, call: undefined, type: identifier_1.ReferenceType.Argument }),
114
- });
116
+ origin: [origin],
117
+ link
118
+ }, !nextGraph.hasVertex(rootId) || nextGraph.isRoot(rootId), true);
115
119
  for (const arg of argumentProcessResult) {
116
120
  if (arg) {
117
121
  nextGraph.addEdge(rootId, arg.entryPoint, edge_1.EdgeType.Argument);
@@ -8,7 +8,7 @@ import type { NodeId } from '../../../../../r-bridge/lang-4.x/ast/model/processi
8
8
  import type { RNode } from '../../../../../r-bridge/lang-4.x/ast/model/model';
9
9
  import type { IdentifierReference } from '../../../../environments/identifier';
10
10
  import { DataflowGraph } from '../../../../graph/graph';
11
- import type { ContainerIndicesCollection } from '../../../../graph/vertex';
11
+ import type { ContainerIndicesCollection, FunctionOriginInformation } from '../../../../graph/vertex';
12
12
  export interface ProcessKnownFunctionCallInput<OtherInfo> extends ForceArguments {
13
13
  readonly name: RSymbol<OtherInfo & ParentInformation>;
14
14
  readonly args: readonly (RNode<OtherInfo & ParentInformation> | RFunctionArgument<OtherInfo & ParentInformation>)[];
@@ -22,6 +22,7 @@ export interface ProcessKnownFunctionCallInput<OtherInfo> extends ForceArguments
22
22
  readonly patchData?: (data: DataflowProcessorInformation<OtherInfo & ParentInformation>, arg: number) => DataflowProcessorInformation<OtherInfo & ParentInformation>;
23
23
  /** Does the call have a side effect that we do not know a lot about which may have further consequences? */
24
24
  readonly hasUnknownSideEffect?: boolean;
25
+ readonly origin: FunctionOriginInformation | 'default';
25
26
  }
26
27
  export interface ProcessKnownFunctionCallResult {
27
28
  readonly information: DataflowInformation;
@@ -29,4 +30,4 @@ export interface ProcessKnownFunctionCallResult {
29
30
  readonly fnRef: IdentifierReference;
30
31
  }
31
32
  export declare function markNonStandardEvaluationEdges(markAsNSE: readonly number[], callArgs: readonly (DataflowInformation | undefined)[], finalGraph: DataflowGraph, rootId: NodeId): void;
32
- export declare function processKnownFunctionCall<OtherInfo>({ name, args, rootId, data, reverseOrder, markAsNSE, forceArgs, patchData, hasUnknownSideEffect }: ProcessKnownFunctionCallInput<OtherInfo>, indicesCollection?: ContainerIndicesCollection): ProcessKnownFunctionCallResult;
33
+ export declare function processKnownFunctionCall<OtherInfo>({ name, args, rootId, data, reverseOrder, markAsNSE, forceArgs, patchData, hasUnknownSideEffect, origin }: ProcessKnownFunctionCallInput<OtherInfo>, indicesCollection?: ContainerIndicesCollection): ProcessKnownFunctionCallResult;
@@ -23,7 +23,7 @@ function markNonStandardEvaluationEdges(markAsNSE, callArgs, finalGraph, rootId)
23
23
  }
24
24
  }
25
25
  }
26
- function processKnownFunctionCall({ name, args, rootId, data, reverseOrder = false, markAsNSE = undefined, forceArgs, patchData = d => d, hasUnknownSideEffect }, indicesCollection = undefined) {
26
+ function processKnownFunctionCall({ name, args, rootId, data, reverseOrder = false, markAsNSE = undefined, forceArgs, patchData = d => d, hasUnknownSideEffect, origin }, indicesCollection = undefined) {
27
27
  const functionName = (0, processor_1.processDataflowFor)(name, data);
28
28
  const finalGraph = new graph_1.DataflowGraph(data.completeAst.idMap);
29
29
  const functionCallName = name.content;
@@ -43,6 +43,7 @@ function processKnownFunctionCall({ name, args, rootId, data, reverseOrder = fal
43
43
  cds: data.controlDependencies,
44
44
  args: reverseOrder ? [...callArgs].reverse() : callArgs,
45
45
  indicesCollection: indicesCollection,
46
+ origin: origin === 'default' ? ['function'] : [origin]
46
47
  });
47
48
  if (hasUnknownSideEffect) {
48
49
  finalGraph.markIdForUnknownSideEffects(rootId);
@@ -4,4 +4,6 @@ import type { ParentInformation } from '../../../../../r-bridge/lang-4.x/ast/mod
4
4
  import type { RFunctionArgument } from '../../../../../r-bridge/lang-4.x/ast/model/nodes/r-function-call';
5
5
  import type { RSymbol } from '../../../../../r-bridge/lang-4.x/ast/model/nodes/r-symbol';
6
6
  import type { NodeId } from '../../../../../r-bridge/lang-4.x/ast/model/processing/node-id';
7
+ import type { DataflowGraph } from '../../../../graph/graph';
8
+ export declare function markAsOnlyBuiltIn(graph: DataflowGraph, rootId: NodeId): void;
7
9
  export declare function processNamedCall<OtherInfo>(name: RSymbol<OtherInfo & ParentInformation>, args: readonly RFunctionArgument<OtherInfo & ParentInformation>[], rootId: NodeId, data: DataflowProcessorInformation<OtherInfo & ParentInformation>): DataflowInformation;
@@ -1,5 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.markAsOnlyBuiltIn = markAsOnlyBuiltIn;
3
4
  exports.processNamedCall = processNamedCall;
4
5
  const info_1 = require("../../../../info");
5
6
  const known_call_handling_1 = require("./known-call-handling");
@@ -24,9 +25,16 @@ function mergeInformation(info, newInfo) {
24
25
  function processDefaultFunctionProcessor(information, name, args, rootId, data) {
25
26
  const resolve = (0, resolve_by_name_1.resolveByName)(name.content, data.environment, identifier_1.ReferenceType.Function);
26
27
  /* if we do not know where we land, we force! */
27
- const call = (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data, forceArgs: (resolve?.length ?? 0) > 0 ? undefined : 'all' });
28
+ const call = (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data, forceArgs: (resolve?.length ?? 0) > 0 ? undefined : 'all', origin: 'default' });
28
29
  return mergeInformation(information, call.information);
29
30
  }
31
+ function markAsOnlyBuiltIn(graph, rootId) {
32
+ const v = graph.getVertex(rootId);
33
+ if (v?.tag === vertex_1.VertexType.FunctionCall) {
34
+ v.onlyBuiltin = true;
35
+ v.environment = undefined;
36
+ }
37
+ }
30
38
  function processNamedCall(name, args, rootId, data) {
31
39
  const resolved = (0, resolve_by_name_1.resolveByName)(name.content, data.environment, identifier_1.ReferenceType.Function) ?? [];
32
40
  let defaultProcessor = resolved.length === 0;
@@ -46,11 +54,7 @@ function processNamedCall(name, args, rootId, data) {
46
54
  }
47
55
  else if (information && builtIn) {
48
56
  // mark the function call as built in only
49
- const v = information.graph.getVertex(rootId);
50
- if (v?.tag === vertex_1.VertexType.FunctionCall) {
51
- v.onlyBuiltin = true;
52
- v.environment = undefined;
53
- }
57
+ markAsOnlyBuiltIn(information.graph, rootId);
54
58
  }
55
59
  return information ?? (0, info_1.initializeCleanDataflowInformation)(rootId, data);
56
60
  }
@@ -3,4 +3,5 @@ import type { DataflowInformation } from '../../../../info';
3
3
  import type { RUnnamedFunctionCall } from '../../../../../r-bridge/lang-4.x/ast/model/nodes/r-function-call';
4
4
  import type { ParentInformation } from '../../../../../r-bridge/lang-4.x/ast/model/processing/decorate';
5
5
  export declare const UnnamedFunctionCallPrefix = "unnamed-function-call-";
6
+ export declare const UnnamedFunctionCallOrigin = "unnamed";
6
7
  export declare function processUnnamedFunctionCall<OtherInfo>(functionCall: RUnnamedFunctionCall<OtherInfo & ParentInformation>, data: DataflowProcessorInformation<OtherInfo & ParentInformation>): DataflowInformation;