@eagleoutice/flowr 2.7.6 → 2.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (208) hide show
  1. package/README.md +67 -64
  2. package/cli/wiki.js +1 -1
  3. package/control-flow/extract-cfg.js +3 -3
  4. package/control-flow/useless-loop.d.ts +1 -1
  5. package/control-flow/useless-loop.js +2 -2
  6. package/dataflow/cluster.js +3 -3
  7. package/dataflow/environments/built-in-config.d.ts +8 -4
  8. package/dataflow/environments/built-in.d.ts +27 -14
  9. package/dataflow/environments/built-in.js +27 -12
  10. package/dataflow/environments/default-builtin-config.d.ts +614 -3
  11. package/dataflow/environments/default-builtin-config.js +50 -15
  12. package/dataflow/environments/environment.js +3 -2
  13. package/dataflow/environments/identifier.d.ts +5 -1
  14. package/dataflow/environments/reference-to-maybe.d.ts +2 -2
  15. package/dataflow/environments/reference-to-maybe.js +23 -14
  16. package/dataflow/environments/resolve-by-name.d.ts +6 -2
  17. package/dataflow/environments/resolve-by-name.js +5 -1
  18. package/dataflow/environments/scoping.js +1 -3
  19. package/dataflow/eval/resolve/alias-tracking.js +5 -1
  20. package/dataflow/extractor.js +3 -3
  21. package/dataflow/fn/exceptions-of-function.d.ts +13 -0
  22. package/dataflow/fn/exceptions-of-function.js +47 -0
  23. package/dataflow/fn/higher-order-function.d.ts +1 -1
  24. package/dataflow/fn/higher-order-function.js +3 -3
  25. package/dataflow/fn/recursive-function.d.ts +6 -0
  26. package/dataflow/fn/recursive-function.js +32 -0
  27. package/dataflow/graph/call-graph.d.ts +10 -0
  28. package/dataflow/graph/call-graph.js +209 -0
  29. package/dataflow/graph/dataflowgraph-builder.d.ts +7 -2
  30. package/dataflow/graph/dataflowgraph-builder.js +14 -9
  31. package/dataflow/graph/diff-dataflow-graph.js +96 -2
  32. package/dataflow/graph/graph.d.ts +10 -7
  33. package/dataflow/graph/graph.js +7 -8
  34. package/dataflow/graph/vertex.d.ts +6 -3
  35. package/dataflow/hooks.d.ts +30 -0
  36. package/dataflow/hooks.js +38 -0
  37. package/dataflow/info.d.ts +28 -5
  38. package/dataflow/info.js +66 -31
  39. package/dataflow/internal/linker.d.ts +13 -3
  40. package/dataflow/internal/linker.js +155 -53
  41. package/dataflow/internal/process/functions/call/argument/unpack-argument.d.ts +4 -0
  42. package/dataflow/internal/process/functions/call/argument/unpack-argument.js +7 -0
  43. package/dataflow/internal/process/functions/call/built-in/built-in-apply.d.ts +1 -1
  44. package/dataflow/internal/process/functions/call/built-in/built-in-apply.js +19 -3
  45. package/dataflow/internal/process/functions/call/built-in/built-in-assignment.d.ts +14 -0
  46. package/dataflow/internal/process/functions/call/built-in/built-in-assignment.js +30 -0
  47. package/dataflow/internal/process/functions/call/built-in/built-in-eval.js +2 -1
  48. package/dataflow/internal/process/functions/call/built-in/built-in-expression-list.js +24 -17
  49. package/dataflow/internal/process/functions/call/built-in/built-in-for-loop.js +2 -1
  50. package/dataflow/internal/process/functions/call/built-in/built-in-function-definition.d.ts +5 -1
  51. package/dataflow/internal/process/functions/call/built-in/built-in-function-definition.js +59 -21
  52. package/dataflow/internal/process/functions/call/built-in/built-in-if-then-else.js +4 -3
  53. package/dataflow/internal/process/functions/call/built-in/built-in-register-hook.d.ts +34 -0
  54. package/dataflow/internal/process/functions/call/built-in/built-in-register-hook.js +92 -0
  55. package/dataflow/internal/process/functions/call/built-in/built-in-repeat-loop.js +1 -0
  56. package/dataflow/internal/process/functions/call/built-in/built-in-stop-if-not.d.ts +21 -0
  57. package/dataflow/internal/process/functions/call/built-in/built-in-stop-if-not.js +129 -0
  58. package/dataflow/internal/process/functions/call/built-in/built-in-try-catch.d.ts +16 -0
  59. package/dataflow/internal/process/functions/call/built-in/built-in-try-catch.js +127 -0
  60. package/dataflow/internal/process/functions/call/built-in/built-in-while-loop.js +5 -3
  61. package/dataflow/internal/process/functions/call/common.d.ts +13 -1
  62. package/dataflow/internal/process/functions/call/common.js +33 -2
  63. package/dataflow/internal/process/functions/call/known-call-handling.d.ts +13 -1
  64. package/dataflow/internal/process/functions/call/known-call-handling.js +29 -3
  65. package/dataflow/internal/process/functions/call/named-call-handling.js +2 -1
  66. package/dataflow/internal/process/functions/call/unnamed-call-handling.js +6 -4
  67. package/dataflow/internal/process/functions/process-argument.js +7 -6
  68. package/dataflow/internal/process/functions/process-parameter.js +2 -1
  69. package/dataflow/internal/process/process-named-call.d.ts +2 -2
  70. package/dataflow/internal/process/process-symbol.js +3 -2
  71. package/dataflow/internal/process/process-value.d.ts +3 -2
  72. package/dataflow/internal/process/process-value.js +8 -6
  73. package/dataflow/origin/dfg-get-origin.js +2 -1
  74. package/dataflow/origin/dfg-get-symbol-refs.js +1 -1
  75. package/documentation/doc-readme.d.ts +1 -1
  76. package/documentation/doc-readme.js +6 -6
  77. package/documentation/doc-util/doc-code.js +1 -1
  78. package/documentation/doc-util/doc-dfg.d.ts +1 -0
  79. package/documentation/doc-util/doc-dfg.js +7 -4
  80. package/documentation/doc-util/doc-query.d.ts +1 -0
  81. package/documentation/doc-util/doc-query.js +1 -1
  82. package/documentation/doc-util/doc-repl.d.ts +2 -1
  83. package/documentation/doc-util/doc-repl.js +11 -3
  84. package/documentation/wiki-analyzer.js +2 -0
  85. package/documentation/wiki-dataflow-graph.js +59 -16
  86. package/documentation/wiki-interface.js +33 -5
  87. package/documentation/wiki-mk/doc-context.d.ts +2 -1
  88. package/documentation/wiki-mk/doc-context.js +2 -2
  89. package/documentation/wiki-mk/doc-maker.js +4 -3
  90. package/documentation/wiki-normalized-ast.js +6 -0
  91. package/documentation/wiki-query.js +109 -1
  92. package/linter/linter-rules.d.ts +1 -1
  93. package/linter/rules/seeded-randomness.js +17 -12
  94. package/linter/rules/useless-loop.d.ts +1 -1
  95. package/package.json +9 -9
  96. package/project/cache/flowr-analyzer-cache.d.ts +11 -0
  97. package/project/cache/flowr-analyzer-cache.js +19 -0
  98. package/project/context/flowr-analyzer-dependencies-context.d.ts +6 -1
  99. package/project/context/flowr-analyzer-dependencies-context.js +6 -0
  100. package/project/context/flowr-analyzer-files-context.d.ts +5 -2
  101. package/project/context/flowr-analyzer-files-context.js +24 -17
  102. package/project/context/flowr-file.d.ts +9 -4
  103. package/project/context/flowr-file.js +20 -6
  104. package/project/flowr-analyzer.d.ts +11 -0
  105. package/project/flowr-analyzer.js +6 -0
  106. package/project/plugins/file-plugins/files/flowr-description-file.d.ts +8 -0
  107. package/project/plugins/file-plugins/files/flowr-description-file.js +36 -3
  108. package/project/plugins/file-plugins/files/flowr-jupyter-file.js +1 -1
  109. package/project/plugins/file-plugins/files/flowr-namespace-file.js +1 -1
  110. package/project/plugins/file-plugins/files/flowr-news-file.js +1 -1
  111. package/project/plugins/file-plugins/files/flowr-rmarkdown-file.js +1 -1
  112. package/project/plugins/file-plugins/flowr-analyzer-description-file-plugin.js +1 -1
  113. package/project/plugins/file-plugins/flowr-analyzer-file-plugin.d.ts +4 -1
  114. package/project/plugins/file-plugins/flowr-analyzer-file-plugin.js +3 -0
  115. package/project/plugins/file-plugins/{flowr-analyzer-namespace-file-plugin.d.ts → flowr-analyzer-namespace-files-plugin.d.ts} +1 -1
  116. package/project/plugins/file-plugins/{flowr-analyzer-namespace-file-plugin.js → flowr-analyzer-namespace-files-plugin.js} +4 -4
  117. package/project/plugins/file-plugins/flowr-analyzer-test-file-plugin.d.ts +26 -0
  118. package/project/plugins/file-plugins/flowr-analyzer-test-file-plugin.js +39 -0
  119. package/project/plugins/file-plugins/flowr-analyzer-vignette-file-plugin.d.ts +26 -0
  120. package/project/plugins/file-plugins/flowr-analyzer-vignette-file-plugin.js +39 -0
  121. package/project/plugins/flowr-analyzer-plugin-defaults.js +6 -2
  122. package/project/plugins/package-version-plugins/flowr-analyzer-package-versions-description-file-plugin.js +3 -13
  123. package/project/plugins/package-version-plugins/package.d.ts +1 -1
  124. package/project/plugins/package-version-plugins/package.js +3 -3
  125. package/project/plugins/plugin-registry.d.ts +4 -2
  126. package/project/plugins/plugin-registry.js +6 -2
  127. package/project/plugins/project-discovery/flowr-analyzer-project-discovery-plugin.d.ts +11 -0
  128. package/project/plugins/project-discovery/flowr-analyzer-project-discovery-plugin.js +5 -2
  129. package/queries/catalog/call-context-query/call-context-query-format.d.ts +4 -12
  130. package/queries/catalog/call-graph-query/call-graph-query-executor.d.ts +6 -0
  131. package/queries/catalog/call-graph-query/call-graph-query-executor.js +21 -0
  132. package/queries/catalog/call-graph-query/call-graph-query-format.d.ts +21 -0
  133. package/queries/catalog/call-graph-query/call-graph-query-format.js +32 -0
  134. package/queries/catalog/dataflow-query/dataflow-query-executor.js +4 -3
  135. package/queries/catalog/dependencies-query/dependencies-query-executor.js +29 -3
  136. package/queries/catalog/dependencies-query/dependencies-query-format.d.ts +1 -0
  137. package/queries/catalog/dependencies-query/function-info/function-info.d.ts +8 -1
  138. package/queries/catalog/dependencies-query/function-info/write-functions.js +13 -0
  139. package/queries/catalog/does-call-query/does-call-query-executor.d.ts +6 -0
  140. package/queries/catalog/does-call-query/does-call-query-executor.js +100 -0
  141. package/queries/catalog/does-call-query/does-call-query-format.d.ts +51 -0
  142. package/queries/catalog/does-call-query/does-call-query-format.js +102 -0
  143. package/queries/catalog/files-query/files-query-executor.js +4 -4
  144. package/queries/catalog/files-query/files-query-format.d.ts +2 -1
  145. package/queries/catalog/files-query/files-query-format.js +18 -2
  146. package/queries/catalog/id-map-query/id-map-query-executor.js +4 -3
  147. package/queries/catalog/inspect-exceptions-query/inspect-exception-query-executor.d.ts +18 -0
  148. package/queries/catalog/inspect-exceptions-query/inspect-exception-query-executor.js +56 -0
  149. package/queries/catalog/inspect-exceptions-query/inspect-exception-query-format.d.ts +34 -0
  150. package/queries/catalog/inspect-exceptions-query/inspect-exception-query-format.js +54 -0
  151. package/queries/catalog/inspect-higher-order-query/inspect-higher-order-query-executor.js +3 -28
  152. package/queries/catalog/inspect-higher-order-query/inspect-higher-order-query-format.d.ts +6 -0
  153. package/queries/catalog/inspect-higher-order-query/inspect-higher-order-query-format.js +12 -0
  154. package/queries/catalog/inspect-recursion-query/inspect-recursion-query-executor.d.ts +6 -0
  155. package/queries/catalog/inspect-recursion-query/inspect-recursion-query-executor.js +23 -0
  156. package/queries/catalog/inspect-recursion-query/inspect-recursion-query-format.d.ts +28 -0
  157. package/queries/catalog/inspect-recursion-query/inspect-recursion-query-format.js +44 -0
  158. package/queries/catalog/linter-query/linter-query-format.js +4 -1
  159. package/queries/catalog/location-map-query/location-map-query-executor.js +1 -1
  160. package/queries/catalog/normalized-ast-query/normalized-ast-query-executor.js +4 -3
  161. package/queries/catalog/project-query/project-query-executor.js +9 -3
  162. package/queries/catalog/project-query/project-query-format.d.ts +6 -1
  163. package/queries/catalog/project-query/project-query-format.js +35 -9
  164. package/queries/query.d.ts +34 -2
  165. package/queries/query.js +9 -0
  166. package/r-bridge/data/data.d.ts +10 -5
  167. package/r-bridge/data/data.js +11 -5
  168. package/r-bridge/lang-4.x/ast/model/model.d.ts +7 -7
  169. package/r-bridge/lang-4.x/ast/model/nodes/r-access.d.ts +2 -2
  170. package/r-bridge/lang-4.x/ast/model/nodes/r-argument.d.ts +2 -2
  171. package/r-bridge/lang-4.x/ast/model/nodes/r-binary-op.d.ts +2 -2
  172. package/r-bridge/lang-4.x/ast/model/nodes/r-comment.d.ts +5 -2
  173. package/r-bridge/lang-4.x/ast/model/nodes/r-comment.js +8 -0
  174. package/r-bridge/lang-4.x/ast/model/nodes/r-expression-list.d.ts +2 -2
  175. package/r-bridge/lang-4.x/ast/model/nodes/r-for-loop.d.ts +2 -2
  176. package/r-bridge/lang-4.x/ast/model/nodes/r-function-call.d.ts +3 -3
  177. package/r-bridge/lang-4.x/ast/model/nodes/r-function-definition.d.ts +2 -2
  178. package/r-bridge/lang-4.x/ast/model/nodes/r-if-then-else.d.ts +2 -2
  179. package/r-bridge/lang-4.x/ast/model/nodes/r-parameter.d.ts +2 -2
  180. package/r-bridge/lang-4.x/ast/model/nodes/r-pipe.d.ts +2 -2
  181. package/r-bridge/lang-4.x/ast/model/nodes/r-repeat-loop.d.ts +2 -2
  182. package/r-bridge/lang-4.x/ast/model/nodes/r-unary-op.d.ts +2 -2
  183. package/r-bridge/lang-4.x/ast/model/nodes/r-while-loop.d.ts +2 -2
  184. package/r-bridge/lang-4.x/ast/parser/main/internal/other/normalize-comment.js +0 -1
  185. package/r-bridge/lang-4.x/tree-sitter/tree-sitter-normalize.js +0 -2
  186. package/r-bridge/roxygen2/roxygen-ast.d.ts +218 -0
  187. package/r-bridge/roxygen2/roxygen-ast.js +82 -0
  188. package/r-bridge/roxygen2/roxygen-parse.d.ts +24 -0
  189. package/r-bridge/roxygen2/roxygen-parse.js +214 -0
  190. package/reconstruct/auto-select/magic-comments.js +4 -4
  191. package/slicing/static/slice-call.js +3 -4
  192. package/slicing/static/static-slicer.js +2 -2
  193. package/statistics/features/supported/defined-functions/defined-functions.js +1 -1
  194. package/util/collections/defaultmap.d.ts +3 -3
  195. package/util/mermaid/dfg.js +5 -5
  196. package/util/objects.js +1 -1
  197. package/util/r-author.d.ts +5 -0
  198. package/util/r-author.js +110 -0
  199. package/util/r-license.d.ts +10 -1
  200. package/util/r-license.js +27 -6
  201. package/util/r-version.d.ts +19 -0
  202. package/util/r-version.js +106 -0
  203. package/util/range.d.ts +6 -0
  204. package/util/range.js +7 -0
  205. package/util/simple-df/dfg-ascii.js +2 -2
  206. package/util/text/args.d.ts +9 -0
  207. package/util/text/args.js +65 -0
  208. package/util/version.js +1 -1
@@ -0,0 +1,209 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.computeCallGraph = computeCallGraph;
4
+ const graph_1 = require("./graph");
5
+ const vertex_1 = require("./vertex");
6
+ const linker_1 = require("../internal/linker");
7
+ const edge_1 = require("./edge");
8
+ const built_in_1 = require("../environments/built-in");
9
+ const defaultmap_1 = require("../../util/collections/defaultmap");
10
+ function reaches(from, to, graph, knownReachability) {
11
+ const visited = new Set();
12
+ const toVisit = [from];
13
+ while (toVisit.length > 0) {
14
+ const currentId = toVisit.pop();
15
+ if (visited.has(currentId)) {
16
+ continue;
17
+ }
18
+ if (currentId === to) {
19
+ knownReachability.get(from).add(to);
20
+ return true;
21
+ }
22
+ else if (knownReachability.get(currentId).has(to)) {
23
+ knownReachability.get(from).add(to);
24
+ return true;
25
+ }
26
+ visited.add(currentId);
27
+ for (const [tar] of graph.outgoingEdges(currentId) ?? []) {
28
+ toVisit.push(tar);
29
+ }
30
+ }
31
+ return false;
32
+ }
33
+ /**
34
+ * Computes the call graph from the given dataflow graph.
35
+ */
36
+ function computeCallGraph(graph) {
37
+ const result = new graph_1.DataflowGraph(graph.idMap);
38
+ const state = {
39
+ visited: new Set(),
40
+ potentials: [],
41
+ knownReachability: new defaultmap_1.DefaultMap(() => new Set())
42
+ };
43
+ for (const [, vert] of graph.vertices(false)) {
44
+ if (vert?.tag === vertex_1.VertexType.FunctionCall) {
45
+ processCall(vert, undefined, graph, result, state);
46
+ }
47
+ else if (vert?.tag === vertex_1.VertexType.FunctionDefinition) {
48
+ processFunctionDefinition(vert, undefined, graph, result, state);
49
+ }
50
+ }
51
+ for (const [from, tos] of state.potentials) {
52
+ for (const to of tos) {
53
+ if (!result.hasVertex(to)) {
54
+ const v = graph.getVertex(to, true);
55
+ if (v) {
56
+ processUnknown(v, from, graph, result, state);
57
+ if (v.tag === vertex_1.VertexType.FunctionDefinition) {
58
+ processFunctionDefinition(v, from, graph, result, state);
59
+ }
60
+ }
61
+ }
62
+ else if (!reaches(from, to, result, state.knownReachability)) {
63
+ result.addEdge(from, to, edge_1.EdgeType.Calls);
64
+ }
65
+ }
66
+ }
67
+ return result;
68
+ }
69
+ function processCds(vtx, graph, result, state) {
70
+ for (const tar of vtx.controlDependencies ?? []) {
71
+ const targetVtx = graph.getVertex(tar.id, true);
72
+ if (targetVtx) {
73
+ processUnknown(targetVtx, undefined, graph, result, state);
74
+ }
75
+ }
76
+ }
77
+ /**
78
+ * This tracks the known symbol origins for a function call for which we know that flowr found no targets!
79
+ */
80
+ function fallbackUntargetedCall(vtx, graph) {
81
+ // we track all aliases to their roots here, we know there is no known call target
82
+ const collected = new Set();
83
+ const visited = new Set();
84
+ const toVisit = [vtx.id];
85
+ while (toVisit.length > 0) {
86
+ const currentId = toVisit.pop();
87
+ if (visited.has(currentId)) {
88
+ continue;
89
+ }
90
+ visited.add(currentId);
91
+ const currentVtx = graph.getVertex(currentId, true);
92
+ if (!currentVtx) {
93
+ continue;
94
+ }
95
+ let addedNew = false;
96
+ for (const [tar, { types }] of graph.outgoingEdges(currentId) ?? []) {
97
+ if ((0, edge_1.edgeIncludesType)(types, edge_1.EdgeType.Reads | edge_1.EdgeType.DefinedByOnCall | edge_1.EdgeType.DefinedBy | edge_1.EdgeType.Returns) && (0, edge_1.edgeDoesNotIncludeType)(types, edge_1.EdgeType.NonStandardEvaluation | edge_1.EdgeType.Argument)) {
98
+ addedNew = true;
99
+ toVisit.push(tar);
100
+ }
101
+ }
102
+ // we have reached our end(s)
103
+ if (!addedNew && currentId !== vtx.id) {
104
+ collected.add(currentId);
105
+ }
106
+ }
107
+ return collected;
108
+ }
109
+ function processCall(vtx, from, graph, result, state) {
110
+ if (from && !reaches(from, vtx.id, result, state.knownReachability)) {
111
+ result.addEdge(from, vtx.id, edge_1.EdgeType.Calls);
112
+ }
113
+ if (state.visited.has(vtx.id)) {
114
+ return;
115
+ }
116
+ result.addVertex(vtx, undefined, true);
117
+ processCds(vtx, graph, result, state);
118
+ state.visited.add(vtx.id);
119
+ // for each call, resolve the targets
120
+ const tars = (0, linker_1.getAllFunctionCallTargets)(vtx.id, graph, vtx.environment);
121
+ let addedTarget = false;
122
+ for (const tar of tars) {
123
+ if ((0, built_in_1.isBuiltIn)(tar)) {
124
+ result.addEdge(vtx.id, tar, edge_1.EdgeType.Calls);
125
+ addedTarget = true;
126
+ continue;
127
+ }
128
+ const targetVtx = graph.getVertex(tar, true);
129
+ if (targetVtx?.tag !== vertex_1.VertexType.FunctionDefinition) {
130
+ continue;
131
+ }
132
+ addedTarget = true;
133
+ processFunctionDefinition(targetVtx, vtx.id, graph, result, state);
134
+ }
135
+ if (vtx.origin !== 'unnamed') {
136
+ for (const origs of vtx.origin) {
137
+ if (origs.startsWith('builtin:')) {
138
+ addedTarget = true;
139
+ result.addEdge(vtx.id, (0, built_in_1.builtInId)(origs.substring('builtin:'.length)), edge_1.EdgeType.Calls);
140
+ }
141
+ }
142
+ }
143
+ if (!addedTarget) {
144
+ const origs = fallbackUntargetedCall(vtx, graph);
145
+ for (const ori of origs) {
146
+ const oriVtx = graph.getVertex(ori, true);
147
+ if (!oriVtx) {
148
+ continue;
149
+ }
150
+ result.addEdge(vtx.id, ori, edge_1.EdgeType.Calls);
151
+ const name = graph.idMap?.get(ori);
152
+ if (name?.lexeme && oriVtx.tag === vertex_1.VertexType.Use) {
153
+ result.addVertex({
154
+ ...oriVtx,
155
+ tag: vertex_1.VertexType.FunctionCall,
156
+ name: name.lexeme,
157
+ onlyBuiltin: false,
158
+ origin: ['function'],
159
+ args: []
160
+ }, oriVtx.environment);
161
+ }
162
+ }
163
+ }
164
+ // handle arguments, traversing the 'reads' and the 'returns' edges
165
+ for (const [tar, { types }] of graph.outgoingEdges(vtx.id) ?? []) {
166
+ if ((0, edge_1.edgeDoesNotIncludeType)(types, edge_1.EdgeType.Reads | edge_1.EdgeType.Returns | edge_1.EdgeType.Argument)) {
167
+ continue;
168
+ }
169
+ const tVtx = graph.getVertex(tar, true);
170
+ if (!tVtx) {
171
+ continue;
172
+ }
173
+ processUnknown(tVtx, vtx.id, graph, result, state);
174
+ }
175
+ }
176
+ function processUnknown(vtx, from, graph, result, state) {
177
+ switch (vtx.tag) {
178
+ case vertex_1.VertexType.FunctionCall:
179
+ processCall(vtx, from, graph, result, state);
180
+ return;
181
+ case vertex_1.VertexType.FunctionDefinition:
182
+ if (from) {
183
+ result.addEdge(from, (0, built_in_1.builtInId)('function'), edge_1.EdgeType.Calls);
184
+ }
185
+ return;
186
+ default:
187
+ return;
188
+ }
189
+ }
190
+ function processFunctionDefinition(vtx, from, graph, result, state) {
191
+ if (from) {
192
+ result.addEdge(from, vtx.id, edge_1.EdgeType.Calls);
193
+ }
194
+ if (state.visited.has(vtx.id)) {
195
+ return;
196
+ }
197
+ state.visited.add(vtx.id);
198
+ result.addVertex(vtx, undefined, true);
199
+ processCds(vtx, graph, result, state);
200
+ const exits = new Set(vtx.exitPoints);
201
+ for (const { nodeId } of exits) {
202
+ const v = graph.getVertex(nodeId, true);
203
+ if (v) {
204
+ processUnknown(v, vtx.id, graph, result, state);
205
+ }
206
+ }
207
+ state.potentials.push([vtx.id, vtx.subflow.graph.difference(exits)]);
208
+ }
209
+ //# sourceMappingURL=call-graph.js.map
@@ -3,10 +3,11 @@ import type { AstIdMap } from '../../r-bridge/lang-4.x/ast/model/processing/deco
3
3
  import { type DataflowFunctionFlowInformation, DataflowGraph, type FunctionArgument } from './graph';
4
4
  import { type IEnvironment, type REnvironmentInformation } from '../environments/environment';
5
5
  import { type DataflowGraphVertexArgument, type DataflowGraphVertexAstLink, type DataflowGraphVertexInfo, type DataflowGraphVertexUse, type FunctionOriginInformation } from './vertex';
6
- import type { ControlDependency } from '../info';
6
+ import type { ControlDependency, ExitPoint } from '../info';
7
7
  import type { LinkTo } from '../../queries/catalog/call-context-query/call-context-query-format';
8
8
  import type { FlowrSearchLike } from '../../search/flowr-search-builder';
9
9
  import type { ReadonlyFlowrAnalysisProvider } from '../../project/flowr-analyzer';
10
+ import type { HookInformation } from '../hooks';
10
11
  /**
11
12
  * Creates an empty dataflow graph.
12
13
  * Should only be used in tests and documentation.
@@ -31,10 +32,13 @@ export declare class DataflowGraphBuilder<Vertex extends DataflowGraphVertexInfo
31
32
  * @param asRoot - should the vertex be part of the root vertex set of the graph
32
33
  * (i.e., be a valid entry point), or is it nested (e.g., as part of a function definition)
33
34
  */
34
- defineFunction(id: NodeId, exitPoints: readonly NodeId[], subflow: DataflowFunctionFlowInformation, info?: {
35
+ defineFunction(id: NodeId, exitPoints: readonly ExitPoint[] | readonly NodeId[], subflow: Omit<DataflowFunctionFlowInformation, 'hooks'> & {
36
+ hooks?: HookInformation[];
37
+ }, info?: {
35
38
  environment?: REnvironmentInformation;
36
39
  builtInEnvironment?: IEnvironment;
37
40
  controlDependencies?: ControlDependency[];
41
+ readParams?: [NodeId, boolean][];
38
42
  }, asRoot?: boolean): this;
39
43
  /**
40
44
  * Adds a **vertex** for a **function call** (V2).
@@ -54,6 +58,7 @@ export declare class DataflowGraphBuilder<Vertex extends DataflowGraphVertexInfo
54
58
  controlDependencies?: ControlDependency[];
55
59
  origin?: FunctionOriginInformation[];
56
60
  link?: DataflowGraphVertexAstLink;
61
+ omitArgs?: boolean;
57
62
  }, asRoot?: boolean): this;
58
63
  /** automatically adds argument links if they do not already exist */
59
64
  private addArgumentLinks;
@@ -49,16 +49,19 @@ class DataflowGraphBuilder extends graph_1.DataflowGraph {
49
49
  return this.addVertexWithDefaultEnv({
50
50
  tag: vertex_1.VertexType.FunctionDefinition,
51
51
  id: (0, node_id_1.normalizeIdToNumberIfPossible)(id),
52
+ params: Object.fromEntries(info?.readParams ?? []),
52
53
  subflow: {
53
54
  ...subflow,
54
55
  entryPoint: (0, node_id_1.normalizeIdToNumberIfPossible)(subflow.entryPoint),
55
56
  graph: new Set([...subflow.graph].map(node_id_1.normalizeIdToNumberIfPossible)),
56
57
  out: subflow.out.map(o => ({ ...o, nodeId: (0, node_id_1.normalizeIdToNumberIfPossible)(o.nodeId), controlDependencies: o.controlDependencies?.map(c => ({ ...c, id: (0, node_id_1.normalizeIdToNumberIfPossible)(c.id) })) })),
57
58
  in: subflow.in.map(o => ({ ...o, nodeId: (0, node_id_1.normalizeIdToNumberIfPossible)(o.nodeId), controlDependencies: o.controlDependencies?.map(c => ({ ...c, id: (0, node_id_1.normalizeIdToNumberIfPossible)(c.id) })) })),
58
- unknownReferences: subflow.unknownReferences.map(o => ({ ...o, nodeId: (0, node_id_1.normalizeIdToNumberIfPossible)(o.nodeId), controlDependencies: o.controlDependencies?.map(c => ({ ...c, id: (0, node_id_1.normalizeIdToNumberIfPossible)(c.id) })) }))
59
+ unknownReferences: subflow.unknownReferences.map(o => ({ ...o, nodeId: (0, node_id_1.normalizeIdToNumberIfPossible)(o.nodeId), controlDependencies: o.controlDependencies?.map(c => ({ ...c, id: (0, node_id_1.normalizeIdToNumberIfPossible)(c.id) })) })),
60
+ hooks: subflow.hooks ?? []
59
61
  },
60
- exitPoints: exitPoints.map(node_id_1.normalizeIdToNumberIfPossible),
61
- cds: info?.controlDependencies?.map(c => ({ ...c, id: (0, node_id_1.normalizeIdToNumberIfPossible)(c.id) })),
62
+ exitPoints: exitPoints.map(e => typeof e === 'object' ? ({ ...e, nodeId: (0, node_id_1.normalizeIdToNumberIfPossible)(e.nodeId), controlDependencies: e.controlDependencies?.map(c => ({ ...c, id: (0, node_id_1.normalizeIdToNumberIfPossible)(c.id) })) }) :
63
+ ({ nodeId: (0, node_id_1.normalizeIdToNumberIfPossible)(e), type: 0 /* ExitPointType.Default */, controlDependencies: undefined })),
64
+ controlDependencies: info?.controlDependencies?.map(c => ({ ...c, id: (0, node_id_1.normalizeIdToNumberIfPossible)(c.id) })),
62
65
  environment: info?.environment,
63
66
  }, asRoot);
64
67
  }
@@ -79,12 +82,14 @@ class DataflowGraphBuilder extends graph_1.DataflowGraph {
79
82
  name,
80
83
  args: args.map(a => a === r_function_call_1.EmptyArgument ? r_function_call_1.EmptyArgument : { ...a, nodeId: (0, node_id_1.normalizeIdToNumberIfPossible)(a.nodeId), controlDependencies: undefined }),
81
84
  environment: (info?.onlyBuiltIn || onlyBuiltInAuto) ? undefined : info?.environment ?? this.defaultEnvironment,
82
- cds: info?.controlDependencies?.map(c => ({ ...c, id: (0, node_id_1.normalizeIdToNumberIfPossible)(c.id) })),
85
+ controlDependencies: info?.controlDependencies?.map(c => ({ ...c, id: (0, node_id_1.normalizeIdToNumberIfPossible)(c.id) })),
83
86
  onlyBuiltin: info?.onlyBuiltIn ?? onlyBuiltInAuto ?? false,
84
87
  origin: info?.origin ?? [(0, default_builtin_config_1.getDefaultProcessor)(name) ?? 'function'],
85
88
  link: info?.link
86
89
  }, asRoot);
87
- this.addArgumentLinks(id, args);
90
+ if (!info?.omitArgs) {
91
+ this.addArgumentLinks(id, args);
92
+ }
88
93
  if (info?.returns) {
89
94
  for (const ret of info.returns) {
90
95
  this.returns(id, ret);
@@ -129,7 +134,7 @@ class DataflowGraphBuilder extends graph_1.DataflowGraph {
129
134
  tag: vertex_1.VertexType.VariableDefinition,
130
135
  id: (0, node_id_1.normalizeIdToNumberIfPossible)(id),
131
136
  name,
132
- cds: info?.controlDependencies?.map(c => ({ ...c, id: (0, node_id_1.normalizeIdToNumberIfPossible)(c.id) })),
137
+ controlDependencies: info?.controlDependencies?.map(c => ({ ...c, id: (0, node_id_1.normalizeIdToNumberIfPossible)(c.id) })),
133
138
  }, asRoot);
134
139
  if (info?.definedBy) {
135
140
  for (const def of info.definedBy) {
@@ -151,11 +156,11 @@ class DataflowGraphBuilder extends graph_1.DataflowGraph {
151
156
  tag: vertex_1.VertexType.Use,
152
157
  id: (0, node_id_1.normalizeIdToNumberIfPossible)(id),
153
158
  name,
154
- cds: undefined,
159
+ controlDependencies: undefined,
155
160
  environment: undefined
156
161
  }, {
157
162
  ...info,
158
- cds: info?.cds?.map(c => ({ ...c, id: (0, node_id_1.normalizeIdToNumberIfPossible)(c.id) }))
163
+ controlDependencies: info?.controlDependencies?.map(c => ({ ...c, id: (0, node_id_1.normalizeIdToNumberIfPossible)(c.id) }))
159
164
  }), asRoot);
160
165
  }
161
166
  /**
@@ -169,7 +174,7 @@ class DataflowGraphBuilder extends graph_1.DataflowGraph {
169
174
  return this.addVertexWithDefaultEnv({
170
175
  tag: vertex_1.VertexType.Value,
171
176
  id: (0, node_id_1.normalizeIdToNumberIfPossible)(id),
172
- cds: options?.controlDependencies?.map(c => ({ ...c, id: (0, node_id_1.normalizeIdToNumberIfPossible)(c.id) })),
177
+ controlDependencies: options?.controlDependencies?.map(c => ({ ...c, id: (0, node_id_1.normalizeIdToNumberIfPossible)(c.id) })),
173
178
  environment: undefined
174
179
  }, asRoot);
175
180
  }
@@ -168,7 +168,7 @@ function diffVertices(ctx) {
168
168
  });
169
169
  }
170
170
  }
171
- (0, info_1.diffControlDependencies)(lInfo.cds, rInfo.cds, { ...ctx, position: `Vertex ${id} differs in controlDependencies. ` });
171
+ (0, info_1.diffControlDependencies)(lInfo.controlDependencies, rInfo.controlDependencies, { ...ctx, position: `Vertex ${id} differs in controlDependencies. ` });
172
172
  if (lInfo.origin !== undefined || rInfo.origin !== undefined) {
173
173
  // compare arrays
174
174
  const equalArrays = lInfo.origin && rInfo.origin && (0, arrays_1.arrayEqual)(lInfo.origin, rInfo.origin);
@@ -212,7 +212,13 @@ function diffVertices(ctx) {
212
212
  ctx.report.addComment(`Vertex ${id} differs in tags. ${ctx.leftname}: ${lInfo.tag} vs. ${ctx.rightname}: ${rInfo.tag}`, { tag: 'vertex', id });
213
213
  }
214
214
  else {
215
- if (!(0, arrays_1.arrayEqual)(lInfo.exitPoints, rInfo.exitPoints)) {
215
+ if (!(0, arrays_1.arrayEqual)(lInfo.exitPoints, rInfo.exitPoints, (a, b) => {
216
+ if (a.type !== b.type || a.nodeId !== b.nodeId) {
217
+ return false;
218
+ }
219
+ (0, info_1.diffControlDependencies)(a.controlDependencies, b.controlDependencies, { ...ctx, position: '' });
220
+ return true;
221
+ })) {
216
222
  ctx.report.addComment(`Vertex ${id} differs in exit points. ${ctx.leftname}: ${JSON.stringify(lInfo.exitPoints, json_1.jsonReplacer)} vs ${ctx.rightname}: ${JSON.stringify(rInfo.exitPoints, json_1.jsonReplacer)}`, { tag: 'vertex', id });
217
223
  }
218
224
  if ((lInfo.subflow.environment === undefined && rInfo.subflow.environment !== undefined && !ctx.config.leftIsSubgraph)
@@ -222,14 +228,102 @@ function diffVertices(ctx) {
222
228
  position: `${ctx.position}Vertex ${id} (function definition) differs in subflow environments. `
223
229
  });
224
230
  }
231
+ diffInReadParameters(lInfo.params, rInfo.params, {
232
+ ...ctx,
233
+ position: `${ctx.position}Vertex ${id} differs in subflow in-read-parameters. `
234
+ });
225
235
  (0, diff_1.setDifference)(lInfo.subflow.graph, rInfo.subflow.graph, {
226
236
  ...ctx,
227
237
  position: `${ctx.position}Vertex ${id} differs in subflow graph. `
228
238
  });
239
+ diffReferenceLists(id, lInfo.subflow.in, rInfo.subflow.in, {
240
+ ...ctx,
241
+ position: `${ctx.position}Vertex ${id} differs in subflow *in* refs. `
242
+ });
243
+ diffReferenceLists(id, lInfo.subflow.out, rInfo.subflow.out, {
244
+ ...ctx,
245
+ position: `${ctx.position}Vertex ${id} differs in subflow *out* refs. `
246
+ });
247
+ diffReferenceLists(id, lInfo.subflow.unknownReferences, rInfo.subflow.unknownReferences, {
248
+ ...ctx,
249
+ position: `${ctx.position}Vertex ${id} differs in subflow *unknown* refs. `
250
+ });
251
+ diffHooks(lInfo.subflow.hooks, rInfo.subflow.hooks, ctx, id);
252
+ }
253
+ }
254
+ }
255
+ }
256
+ function diffInReadParameters(l, r, ctx) {
257
+ const lKeys = new Set(Object.keys(l));
258
+ const rKeys = new Set(Object.keys(r));
259
+ (0, diff_1.setDifference)(lKeys, rKeys, { ...ctx, position: `${ctx.position}In-read-parameters differ in graphs. ` });
260
+ for (const k of lKeys) {
261
+ const lVal = l[k];
262
+ const rVal = r[k];
263
+ if (rVal === undefined) {
264
+ if (!ctx.config.rightIsSubgraph) {
265
+ ctx.report.addComment(`In-read-parameter ${k} is not present in ${ctx.rightname}`, { tag: 'vertex', id: k });
266
+ }
267
+ continue;
268
+ }
269
+ if (lVal !== rVal) {
270
+ ctx.report.addComment(`In-read-parameter ${k} differs. ${ctx.leftname}: ${lVal} vs ${ctx.rightname}: ${rVal}`, { tag: 'vertex', id: k });
271
+ }
272
+ }
273
+ for (const k of rKeys) {
274
+ if (!lKeys.has(k)) {
275
+ if (!ctx.config.leftIsSubgraph) {
276
+ ctx.report.addComment(`In-read-parameter ${k} is not present in ${ctx.leftname}`, { tag: 'vertex', id: k });
229
277
  }
230
278
  }
231
279
  }
232
280
  }
281
+ function diffReferenceLists(fn, a, b, ctx) {
282
+ // sort by id
283
+ if (a === undefined || b === undefined) {
284
+ if (a !== b) {
285
+ ctx.report.addComment(`${ctx.position}${ctx.leftname}: ${JSON.stringify(a, json_1.jsonReplacer)} vs ${ctx.rightname}: ${JSON.stringify(b, json_1.jsonReplacer)}`, { tag: 'vertex', id: fn });
286
+ }
287
+ return;
288
+ }
289
+ if (a.length !== b.length) {
290
+ ctx.report.addComment(`${ctx.position}Differs in number of references.\n - ${ctx.leftname}: ${JSON.stringify(a, json_1.jsonReplacer)} vs\n - ${ctx.rightname}: ${JSON.stringify(b, json_1.jsonReplacer)}`, { tag: 'vertex', id: fn });
291
+ return;
292
+ }
293
+ const aSorted = [...a].sort((x, y) => x.nodeId.toString().localeCompare(y.nodeId.toString()));
294
+ const bSorted = [...b].sort((x, y) => x.nodeId.toString().localeCompare(y.nodeId.toString()));
295
+ for (let i = 0; i < aSorted.length; ++i) {
296
+ (0, diff_2.diffIdentifierReferences)(aSorted[i], bSorted[i], {
297
+ ...ctx,
298
+ position: `${ctx.position}In reference #${i} ("${aSorted[i].name ?? '?'}", id: ${aSorted[i].nodeId ?? '?'}) `,
299
+ });
300
+ }
301
+ }
302
+ function diffHooks(left, right, ctx, id) {
303
+ // compare length
304
+ if (left.length !== right.length) {
305
+ ctx.report.addComment(`Differs in number of hooks. ${ctx.leftname}: ${JSON.stringify(left, json_1.jsonReplacer)} vs ${ctx.rightname}: ${JSON.stringify(right, json_1.jsonReplacer)}`, { tag: 'vertex', id });
306
+ return;
307
+ }
308
+ // compare each hook
309
+ for (let i = 0; i < left.length; ++i) {
310
+ const lHook = left[i];
311
+ const rHook = right[i];
312
+ if (lHook.type !== rHook.type) {
313
+ ctx.report.addComment(`Hook #${i} differs in type. ${ctx.leftname}: ${JSON.stringify(lHook.type)} vs ${ctx.rightname}: ${JSON.stringify(rHook.type)}`, { tag: 'vertex', id });
314
+ }
315
+ if (lHook.id !== rHook.id) {
316
+ ctx.report.addComment(`Hook #${i} differs in id. ${ctx.leftname}: ${lHook.id} vs ${ctx.rightname}: ${rHook.id}`, { tag: 'vertex', id });
317
+ }
318
+ if (lHook.add !== rHook.add) {
319
+ ctx.report.addComment(`Hook #${i} differs in add. ${ctx.leftname}: ${lHook.add} vs ${ctx.rightname}: ${rHook.add}`, { tag: 'vertex', id });
320
+ }
321
+ if (lHook.after !== rHook.after) {
322
+ ctx.report.addComment(`Hook #${i} differs in after. ${ctx.leftname}: ${lHook.after} vs ${ctx.rightname}: ${rHook.after}`, { tag: 'vertex', id });
323
+ }
324
+ (0, info_1.diffControlDependencies)(lHook.cds, rHook.cds, { ...ctx, position: `Hook #${i} differs in control dependencies. ` });
325
+ }
326
+ }
233
327
  function diffEdge(edge, otherEdge, ctx, id, target) {
234
328
  const edgeTypes = (0, edge_1.splitEdgeTypes)(edge.types);
235
329
  const otherEdgeTypes = (0, edge_1.splitEdgeTypes)(otherEdge.types);
@@ -52,10 +52,6 @@ export declare function isNamedArgument(arg: FunctionArgument): arg is NamedFunc
52
52
  * Returns the reference of a non-empty argument.
53
53
  */
54
54
  export declare function getReferenceOfArgument(arg: FunctionArgument): NodeId | undefined;
55
- /**
56
- * A reference that is enough to indicate start and end points of an edge within the dataflow graph.
57
- */
58
- type ReferenceForEdge = Pick<IdentifierReference, 'nodeId' | 'controlDependencies'> | IdentifierDefinition;
59
55
  /**
60
56
  * Maps the edges target to the edge information
61
57
  */
@@ -184,9 +180,17 @@ export declare class DataflowGraph<Vertex extends DataflowGraphVertexInfo = Data
184
180
  /** {@inheritDoc} */
185
181
  addEdge(from: NodeId, to: NodeId, type: EdgeType | number): this;
186
182
  /** {@inheritDoc} */
187
- addEdge(from: ReferenceForEdge, to: ReferenceForEdge, type: EdgeType | number): this;
183
+ addEdge(from: {
184
+ nodeId: NodeId;
185
+ }, to: {
186
+ nodeId: NodeId;
187
+ }, type: EdgeType | number): this;
188
188
  /** {@inheritDoc} */
189
- addEdge(from: NodeId | ReferenceForEdge, to: NodeId | ReferenceForEdge, type: EdgeType | number): this;
189
+ addEdge(from: NodeId | {
190
+ nodeId: NodeId;
191
+ }, to: NodeId | {
192
+ nodeId: NodeId;
193
+ }, type: EdgeType | number): this;
190
194
  /**
191
195
  * Merges the other graph into *this* one (in-place). The return value is only for convenience.
192
196
  * @param otherGraph - The graph to merge into this one
@@ -222,4 +226,3 @@ export interface IEnvironmentJson {
222
226
  memory: Record<Identifier, IdentifierDefinition[]>;
223
227
  builtInEnv: true | undefined;
224
228
  }
225
- export {};
@@ -206,11 +206,10 @@ class DataflowGraph {
206
206
  return this;
207
207
  }
208
208
  const fallback = vertex.tag === vertex_1.VertexType.FunctionDefinition || (vertex.tag === vertex_1.VertexType.FunctionCall && !vertex.onlyBuiltin) ? fallbackEnv : undefined;
209
- // keep a clone of the original environment
210
- const environment = vertex.environment ? (0, clone_1.cloneEnvironmentInformation)(vertex.environment) : fallback;
211
209
  this.vertexInformation.set(vertex.id, {
212
210
  ...vertex,
213
- environment
211
+ // keep a clone of the original environment
212
+ environment: vertex.environment ? (0, clone_1.cloneEnvironmentInformation)(vertex.environment) : fallback
214
213
  });
215
214
  const has = this.types.get(vertex.tag);
216
215
  if (has) {
@@ -304,7 +303,7 @@ class DataflowGraph {
304
303
  const vertex = this.getVertex(reference.nodeId, true);
305
304
  (0, assert_1.guard)(vertex !== undefined, () => `node must be defined for ${JSON.stringify(reference)} to set reference`);
306
305
  if (vertex.tag === vertex_1.VertexType.FunctionDefinition || vertex.tag === vertex_1.VertexType.VariableDefinition) {
307
- vertex.cds = reference.controlDependencies;
306
+ vertex.controlDependencies = reference.controlDependencies;
308
307
  }
309
308
  else {
310
309
  this.vertexInformation.set(reference.nodeId, { ...vertex, tag: vertex_1.VertexType.VariableDefinition });
@@ -329,17 +328,17 @@ class DataflowGraph {
329
328
  to = to ? (0, node_id_1.normalizeIdToNumberIfPossible)(to) : undefined;
330
329
  const vertex = this.getVertex(from, true);
331
330
  (0, assert_1.guard)(vertex !== undefined, () => `node must be defined for ${from} to add control dependency`);
332
- vertex.cds ??= [];
331
+ vertex.controlDependencies ??= [];
333
332
  if (to) {
334
333
  let hasControlDependency = false;
335
- for (const { id, when: cond } of vertex.cds) {
334
+ for (const { id, when: cond } of vertex.controlDependencies) {
336
335
  if (id === to && when !== cond) {
337
336
  hasControlDependency = true;
338
337
  break;
339
338
  }
340
339
  }
341
340
  if (!hasControlDependency) {
342
- vertex.cds.push({ id: to, when });
341
+ vertex.controlDependencies.push({ id: to, when });
343
342
  }
344
343
  }
345
344
  return this;
@@ -396,7 +395,7 @@ function mergeNodeInfos(current, next) {
396
395
  return current;
397
396
  }
398
397
  /**
399
- * Returns the ids of the dataflow vertices referenced by a {@link ReferenceForEdge}.
398
+ * Returns the ids of the dataflow vertices referenced.
400
399
  */
401
400
  function extractEdgeIds(from, to) {
402
401
  const fromId = typeof from === 'object' ? from.nodeId : from;
@@ -2,7 +2,7 @@ import type { MergeableRecord } from '../../util/objects';
2
2
  import type { DataflowFunctionFlowInformation, FunctionArgument } from './graph';
3
3
  import type { NodeId } from '../../r-bridge/lang-4.x/ast/model/processing/node-id';
4
4
  import type { REnvironmentInformation } from '../environments/environment';
5
- import type { ControlDependency } from '../info';
5
+ import type { ControlDependency, ExitPoint } from '../info';
6
6
  import type { BuiltInMappingName } from '../environments/built-in';
7
7
  export declare enum VertexType {
8
8
  Value = "value",
@@ -137,7 +137,7 @@ interface DataflowGraphVertexBase extends MergeableRecord {
137
137
  /**
138
138
  * @see {@link ControlDependency} - the collection of control dependencies which have an influence on whether the vertex is executed.
139
139
  */
140
- cds: ControlDependency[] | undefined;
140
+ controlDependencies: ControlDependency[] | undefined;
141
141
  /**
142
142
  * this attribute links a vertex to indices (pointer links) it may be affected by or related to
143
143
  */
@@ -235,7 +235,10 @@ export interface DataflowGraphVertexFunctionDefinition extends DataflowGraphVert
235
235
  * All exit points of the function definitions.
236
236
  * In other words: last expressions/return calls
237
237
  */
238
- exitPoints: readonly NodeId[];
238
+ exitPoints: readonly ExitPoint[];
239
+ /** Maps each param to whether it is read, this is an estimate! */
240
+ params: Record<NodeId, boolean>;
241
+ /** The environment in which the function is defined (this is only attached if the DFG deems it necessary). */
239
242
  environment?: REnvironmentInformation;
240
243
  }
241
244
  /**
@@ -0,0 +1,30 @@
1
+ import type { NodeId } from '../r-bridge/lang-4.x/ast/model/processing/node-id';
2
+ import type { ControlDependency } from './info';
3
+ export declare enum KnownHooks {
4
+ /** Triggers on the exit of a function, no matter how this exit is enforced. */
5
+ OnFnExit = "fn-exit"
6
+ }
7
+ /**
8
+ * Information about a registered hook within the dataflow information.
9
+ */
10
+ export interface HookInformation {
11
+ /** The type of the hook */
12
+ type: KnownHooks;
13
+ /** The id of the function definition which is added by the hook */
14
+ id: NodeId;
15
+ /** Control dependencies under which the hook was registered */
16
+ cds?: ControlDependency[];
17
+ /** Whether the hook is added on top of existing ones (true) or replaces them (false) */
18
+ add?: boolean;
19
+ /** Whether the hook is executed after existing ones (true) or before (false) */
20
+ after?: boolean;
21
+ }
22
+ /**
23
+ * Compacts a list of hook registrations by removing redundant and dominated ones.
24
+ */
25
+ export declare function compactHookStates(hooks: HookInformation[]): HookInformation[];
26
+ /**
27
+ * Extracts all hooks of the given type from the list of hooks.
28
+ * Please consider {@link compactHookStates} to remove redundant or dominated hooks first.
29
+ */
30
+ export declare function getHookInformation(hooks: HookInformation[], type: KnownHooks): HookInformation[];
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.KnownHooks = void 0;
4
+ exports.compactHookStates = compactHookStates;
5
+ exports.getHookInformation = getHookInformation;
6
+ const info_1 = require("./info");
7
+ const defaultmap_1 = require("../util/collections/defaultmap");
8
+ var KnownHooks;
9
+ (function (KnownHooks) {
10
+ /** Triggers on the exit of a function, no matter how this exit is enforced. */
11
+ KnownHooks["OnFnExit"] = "fn-exit";
12
+ })(KnownHooks || (exports.KnownHooks = KnownHooks = {}));
13
+ /**
14
+ * Compacts a list of hook registrations by removing redundant and dominated ones.
15
+ */
16
+ function compactHookStates(hooks) {
17
+ const hooksByType = new defaultmap_1.DefaultMap(() => []);
18
+ for (const hook of hooks) {
19
+ if (!hook.add && (0, info_1.happensInEveryBranch)(hook.cds)) {
20
+ hooksByType.set(hook.type, [hook]);
21
+ }
22
+ else if (hook.after) {
23
+ hooksByType.get(hook.type).push(hook);
24
+ }
25
+ else {
26
+ hooksByType.get(hook.type).unshift(hook);
27
+ }
28
+ }
29
+ return hooksByType.values().flatMap(f => f).toArray();
30
+ }
31
+ /**
32
+ * Extracts all hooks of the given type from the list of hooks.
33
+ * Please consider {@link compactHookStates} to remove redundant or dominated hooks first.
34
+ */
35
+ function getHookInformation(hooks, type) {
36
+ return hooks.filter(h => h.type === type);
37
+ }
38
+ //# sourceMappingURL=hooks.js.map