@eagleoutice/flowr 2.9.14 → 2.10.2

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 (214) hide show
  1. package/README.md +52 -29
  2. package/abstract-interpretation/absint-visitor.d.ts +13 -8
  3. package/abstract-interpretation/absint-visitor.js +35 -26
  4. package/abstract-interpretation/data-frame/dataframe-domain.d.ts +1 -2
  5. package/abstract-interpretation/data-frame/dataframe-domain.js +14 -15
  6. package/abstract-interpretation/data-frame/mappers/access-mapper.js +2 -15
  7. package/abstract-interpretation/data-frame/mappers/arguments.d.ts +11 -17
  8. package/abstract-interpretation/data-frame/mappers/arguments.js +18 -18
  9. package/abstract-interpretation/data-frame/mappers/function-mapper.d.ts +41 -15
  10. package/abstract-interpretation/data-frame/mappers/function-mapper.js +74 -48
  11. package/abstract-interpretation/data-frame/mappers/replacement-mapper.js +2 -1
  12. package/abstract-interpretation/data-frame/semantics.d.ts +1 -1
  13. package/abstract-interpretation/data-frame/semantics.js +31 -35
  14. package/abstract-interpretation/data-frame/shape-inference.js +1 -1
  15. package/abstract-interpretation/domains/interval-domain.d.ts +1 -0
  16. package/abstract-interpretation/domains/interval-domain.js +3 -0
  17. package/abstract-interpretation/domains/product-domain.d.ts +9 -0
  18. package/abstract-interpretation/domains/product-domain.js +26 -6
  19. package/abstract-interpretation/domains/state-abstract-domain.d.ts +36 -22
  20. package/abstract-interpretation/domains/state-abstract-domain.js +169 -62
  21. package/abstract-interpretation/unsupported-functions.d.ts +10 -0
  22. package/abstract-interpretation/unsupported-functions.js +45 -0
  23. package/benchmark/slicer.js +10 -13
  24. package/benchmark/stats/stats.d.ts +2 -2
  25. package/cli/flowr.js +1 -1
  26. package/cli/repl/parser/slice-query-parser.d.ts +2 -2
  27. package/config.d.ts +4 -0
  28. package/config.js +5 -3
  29. package/control-flow/control-flow-graph.js +13 -9
  30. package/control-flow/semantic-cfg-guided-visitor.d.ts +6 -0
  31. package/control-flow/semantic-cfg-guided-visitor.js +6 -0
  32. package/dataflow/environments/built-in-proc-name.d.ts +6 -0
  33. package/dataflow/environments/built-in-proc-name.js +6 -0
  34. package/dataflow/environments/built-in.d.ts +7 -5
  35. package/dataflow/environments/built-in.js +2 -0
  36. package/dataflow/environments/default-builtin-config.d.ts +442 -6
  37. package/dataflow/environments/default-builtin-config.js +158 -3
  38. package/dataflow/environments/identifier.d.ts +4 -0
  39. package/dataflow/environments/identifier.js +17 -0
  40. package/dataflow/environments/overwrite.js +2 -5
  41. package/dataflow/graph/call-graph.d.ts +4 -7
  42. package/dataflow/graph/call-graph.js +0 -22
  43. package/dataflow/graph/df-helper.d.ts +23 -12
  44. package/dataflow/graph/df-helper.js +44 -7
  45. package/dataflow/graph/graph-helper.d.ts +9 -4
  46. package/dataflow/graph/graph-helper.js +26 -3
  47. package/dataflow/graph/graph.d.ts +23 -2
  48. package/dataflow/graph/graph.js +38 -4
  49. package/dataflow/graph/vertex.d.ts +2 -0
  50. package/dataflow/instrument/instrument-dataflow-count.d.ts +10 -0
  51. package/dataflow/instrument/instrument-dataflow-count.js +10 -0
  52. package/dataflow/internal/process/functions/call/argument/unpack-argument.d.ts +4 -4
  53. package/dataflow/internal/process/functions/call/built-in/built-in-access.d.ts +3 -3
  54. package/dataflow/internal/process/functions/call/built-in/built-in-apply.d.ts +2 -2
  55. package/dataflow/internal/process/functions/call/built-in/built-in-apply.js +1 -0
  56. package/dataflow/internal/process/functions/call/built-in/built-in-assignment.d.ts +3 -3
  57. package/dataflow/internal/process/functions/call/built-in/built-in-assignment.js +1 -1
  58. package/dataflow/internal/process/functions/call/built-in/built-in-eval.d.ts +2 -2
  59. package/dataflow/internal/process/functions/call/built-in/built-in-expression-list.d.ts +2 -2
  60. package/dataflow/internal/process/functions/call/built-in/built-in-for-loop.d.ts +2 -2
  61. package/dataflow/internal/process/functions/call/built-in/built-in-for-loop.js +1 -1
  62. package/dataflow/internal/process/functions/call/built-in/built-in-function-definition.d.ts +2 -2
  63. package/dataflow/internal/process/functions/call/built-in/built-in-function-definition.js +8 -19
  64. package/dataflow/internal/process/functions/call/built-in/built-in-get.d.ts +2 -2
  65. package/dataflow/internal/process/functions/call/built-in/built-in-if-then-else.d.ts +2 -2
  66. package/dataflow/internal/process/functions/call/built-in/built-in-library.d.ts +2 -2
  67. package/dataflow/internal/process/functions/call/built-in/built-in-list.d.ts +2 -2
  68. package/dataflow/internal/process/functions/call/built-in/built-in-local.d.ts +2 -2
  69. package/dataflow/internal/process/functions/call/built-in/built-in-pipe.d.ts +23 -3
  70. package/dataflow/internal/process/functions/call/built-in/built-in-pipe.js +80 -12
  71. package/dataflow/internal/process/functions/call/built-in/built-in-purrr-formula.d.ts +41 -0
  72. package/dataflow/internal/process/functions/call/built-in/built-in-purrr-formula.js +179 -0
  73. package/dataflow/internal/process/functions/call/built-in/built-in-quote.d.ts +7 -4
  74. package/dataflow/internal/process/functions/call/built-in/built-in-quote.js +62 -1
  75. package/dataflow/internal/process/functions/call/built-in/built-in-recall.d.ts +7 -2
  76. package/dataflow/internal/process/functions/call/built-in/built-in-recall.js +15 -1
  77. package/dataflow/internal/process/functions/call/built-in/built-in-register-hook.d.ts +2 -2
  78. package/dataflow/internal/process/functions/call/built-in/built-in-repeat-loop.d.ts +2 -2
  79. package/dataflow/internal/process/functions/call/built-in/built-in-replacement.d.ts +2 -2
  80. package/dataflow/internal/process/functions/call/built-in/built-in-rm.d.ts +2 -2
  81. package/dataflow/internal/process/functions/call/built-in/built-in-s-seven-dispatch.d.ts +2 -2
  82. package/dataflow/internal/process/functions/call/built-in/built-in-s-seven-new-generic.d.ts +2 -2
  83. package/dataflow/internal/process/functions/call/built-in/built-in-s-three-dispatch.d.ts +2 -2
  84. package/dataflow/internal/process/functions/call/built-in/built-in-source.d.ts +2 -2
  85. package/dataflow/internal/process/functions/call/built-in/built-in-special-bin-op.d.ts +2 -2
  86. package/dataflow/internal/process/functions/call/built-in/built-in-stop-if-not.d.ts +2 -2
  87. package/dataflow/internal/process/functions/call/built-in/built-in-try-catch.d.ts +2 -2
  88. package/dataflow/internal/process/functions/call/built-in/built-in-vector.d.ts +2 -2
  89. package/dataflow/internal/process/functions/call/built-in/built-in-while-loop.d.ts +2 -2
  90. package/dataflow/internal/process/functions/call/common.d.ts +2 -2
  91. package/dataflow/internal/process/functions/call/common.js +6 -4
  92. package/dataflow/internal/process/functions/call/known-call-handling.d.ts +2 -2
  93. package/dataflow/internal/process/functions/call/named-call-handling.d.ts +2 -2
  94. package/dataflow/internal/process/functions/process-parameter.js +1 -1
  95. package/documentation/doc-readme.js +2 -1
  96. package/documentation/wiki-absint.js +6 -5
  97. package/documentation/wiki-analyzer.js +0 -2
  98. package/documentation/wiki-linter.js +6 -0
  99. package/documentation/wiki-normalized-ast.js +7 -7
  100. package/linter/linter-rules.d.ts +49 -1
  101. package/linter/linter-rules.js +5 -1
  102. package/linter/rules/dataframe-access-validation.d.ts +1 -1
  103. package/linter/rules/dataframe-access-validation.js +3 -4
  104. package/linter/rules/problematic-eval.d.ts +44 -0
  105. package/linter/rules/problematic-eval.js +83 -0
  106. package/linter/rules/roxygen-arguments.d.ts +35 -0
  107. package/linter/rules/roxygen-arguments.js +100 -0
  108. package/package.json +8 -9
  109. package/project/context/flowr-analyzer-context.d.ts +1 -8
  110. package/project/context/flowr-analyzer-context.js +1 -7
  111. package/project/context/flowr-analyzer-environment-context.d.ts +5 -0
  112. package/project/context/flowr-analyzer-environment-context.js +6 -0
  113. package/project/context/flowr-analyzer-files-context.d.ts +6 -0
  114. package/project/context/flowr-analyzer-files-context.js +4 -2
  115. package/project/flowr-analyzer-builder.js +1 -4
  116. package/queries/catalog/call-context-query/call-context-query-executor.d.ts +1 -1
  117. package/queries/catalog/call-context-query/call-context-query-executor.js +10 -5
  118. package/queries/catalog/call-context-query/call-context-query-format.d.ts +1 -1
  119. package/queries/catalog/dependencies-query/function-info/library-functions.js +2 -0
  120. package/queries/catalog/df-shape-query/df-shape-query-executor.js +1 -1
  121. package/queries/catalog/df-shape-query/df-shape-query-format.d.ts +3 -3
  122. package/queries/catalog/df-shape-query/df-shape-query-format.js +7 -2
  123. package/queries/catalog/does-call-query/does-call-query-executor.js +1 -1
  124. package/queries/catalog/does-call-query/does-call-query-format.d.ts +2 -2
  125. package/queries/catalog/files-query/files-query-executor.js +0 -1
  126. package/queries/catalog/happens-before-query/happens-before-query-executor.js +2 -2
  127. package/queries/catalog/happens-before-query/happens-before-query-format.d.ts +3 -3
  128. package/queries/catalog/input-sources-query/input-sources-query-executor.d.ts +6 -0
  129. package/queries/catalog/input-sources-query/input-sources-query-executor.js +66 -0
  130. package/queries/catalog/input-sources-query/input-sources-query-format.d.ts +36 -0
  131. package/queries/catalog/input-sources-query/input-sources-query-format.js +63 -0
  132. package/queries/catalog/input-sources-query/simple-input-classifier.d.ts +92 -0
  133. package/queries/catalog/input-sources-query/simple-input-classifier.js +310 -0
  134. package/queries/catalog/inspect-exceptions-query/inspect-exception-query-executor.d.ts +2 -2
  135. package/queries/catalog/inspect-exceptions-query/inspect-exception-query-executor.js +1 -1
  136. package/queries/catalog/inspect-exceptions-query/inspect-exception-query-format.d.ts +2 -2
  137. package/queries/catalog/inspect-higher-order-query/inspect-higher-order-query-executor.js +1 -1
  138. package/queries/catalog/inspect-higher-order-query/inspect-higher-order-query-format.d.ts +2 -2
  139. package/queries/catalog/inspect-recursion-query/inspect-recursion-query-format.d.ts +2 -2
  140. package/queries/catalog/location-map-query/location-map-query-executor.js +1 -1
  141. package/queries/catalog/location-map-query/location-map-query-format.d.ts +2 -2
  142. package/queries/catalog/origin-query/origin-query-executor.d.ts +2 -2
  143. package/queries/catalog/origin-query/origin-query-executor.js +1 -1
  144. package/queries/catalog/origin-query/origin-query-format.d.ts +3 -3
  145. package/queries/catalog/provenance-query/provenance-query-executor.d.ts +1 -4
  146. package/queries/catalog/provenance-query/provenance-query-executor.js +3 -6
  147. package/queries/catalog/provenance-query/provenance-query-format.d.ts +2 -2
  148. package/queries/catalog/resolve-value-query/resolve-value-query-executor.js +1 -1
  149. package/queries/query.d.ts +9 -1
  150. package/queries/query.js +2 -0
  151. package/r-bridge/data/data.d.ts +2 -2
  152. package/r-bridge/data/data.js +2 -2
  153. package/r-bridge/lang-4.x/ast/model/model.d.ts +3 -0
  154. package/r-bridge/lang-4.x/ast/model/model.js +3 -0
  155. package/r-bridge/lang-4.x/ast/model/nodes/r-access.d.ts +16 -1
  156. package/r-bridge/lang-4.x/ast/model/nodes/r-access.js +2 -0
  157. package/r-bridge/lang-4.x/ast/model/nodes/r-argument.d.ts +29 -6
  158. package/r-bridge/lang-4.x/ast/model/nodes/r-argument.js +16 -2
  159. package/r-bridge/lang-4.x/ast/model/nodes/r-binary-op.d.ts +16 -1
  160. package/r-bridge/lang-4.x/ast/model/nodes/r-binary-op.js +2 -0
  161. package/r-bridge/lang-4.x/ast/model/nodes/r-break.d.ts +15 -0
  162. package/r-bridge/lang-4.x/ast/model/nodes/r-break.js +2 -0
  163. package/r-bridge/lang-4.x/ast/model/nodes/r-comment.d.ts +15 -0
  164. package/r-bridge/lang-4.x/ast/model/nodes/r-comment.js +2 -0
  165. package/r-bridge/lang-4.x/ast/model/nodes/r-expression-list.d.ts +16 -1
  166. package/r-bridge/lang-4.x/ast/model/nodes/r-expression-list.js +2 -0
  167. package/r-bridge/lang-4.x/ast/model/nodes/r-for-loop.d.ts +16 -1
  168. package/r-bridge/lang-4.x/ast/model/nodes/r-for-loop.js +2 -0
  169. package/r-bridge/lang-4.x/ast/model/nodes/r-function-call.d.ts +19 -4
  170. package/r-bridge/lang-4.x/ast/model/nodes/r-function-call.js +2 -0
  171. package/r-bridge/lang-4.x/ast/model/nodes/r-function-definition.d.ts +21 -0
  172. package/r-bridge/lang-4.x/ast/model/nodes/r-function-definition.js +16 -0
  173. package/r-bridge/lang-4.x/ast/model/nodes/r-if-then-else.d.ts +16 -1
  174. package/r-bridge/lang-4.x/ast/model/nodes/r-if-then-else.js +2 -0
  175. package/r-bridge/lang-4.x/ast/model/nodes/r-line-directive.d.ts +16 -1
  176. package/r-bridge/lang-4.x/ast/model/nodes/r-line-directive.js +2 -0
  177. package/r-bridge/lang-4.x/ast/model/nodes/r-logical.d.ts +16 -1
  178. package/r-bridge/lang-4.x/ast/model/nodes/r-logical.js +2 -0
  179. package/r-bridge/lang-4.x/ast/model/nodes/r-next.d.ts +16 -1
  180. package/r-bridge/lang-4.x/ast/model/nodes/r-next.js +2 -0
  181. package/r-bridge/lang-4.x/ast/model/nodes/r-number.d.ts +16 -1
  182. package/r-bridge/lang-4.x/ast/model/nodes/r-number.js +2 -0
  183. package/r-bridge/lang-4.x/ast/model/nodes/r-parameter.d.ts +16 -1
  184. package/r-bridge/lang-4.x/ast/model/nodes/r-parameter.js +2 -0
  185. package/r-bridge/lang-4.x/ast/model/nodes/r-pipe.d.ts +25 -1
  186. package/r-bridge/lang-4.x/ast/model/nodes/r-pipe.js +15 -0
  187. package/r-bridge/lang-4.x/ast/model/nodes/r-repeat-loop.d.ts +16 -1
  188. package/r-bridge/lang-4.x/ast/model/nodes/r-repeat-loop.js +2 -0
  189. package/r-bridge/lang-4.x/ast/model/nodes/r-string.d.ts +16 -1
  190. package/r-bridge/lang-4.x/ast/model/nodes/r-string.js +2 -0
  191. package/r-bridge/lang-4.x/ast/model/nodes/r-symbol.d.ts +16 -1
  192. package/r-bridge/lang-4.x/ast/model/nodes/r-symbol.js +2 -0
  193. package/r-bridge/lang-4.x/ast/model/nodes/r-unary-op.d.ts +16 -1
  194. package/r-bridge/lang-4.x/ast/model/nodes/r-unary-op.js +2 -0
  195. package/r-bridge/lang-4.x/ast/model/nodes/r-while-loop.d.ts +16 -1
  196. package/r-bridge/lang-4.x/ast/model/nodes/r-while-loop.js +2 -0
  197. package/r-bridge/lang-4.x/ast/model/versions.d.ts +2 -0
  198. package/r-bridge/lang-4.x/ast/model/versions.js +3 -1
  199. package/r-bridge/roxygen2/documentation-provider.js +15 -6
  200. package/r-bridge/roxygen2/roxygen-ast.d.ts +3 -1
  201. package/search/flowr-search-builder.js +3 -2
  202. package/search/search-executor/search-generators.js +1 -1
  203. package/slicing/criterion/parse.d.ts +11 -10
  204. package/slicing/criterion/parse.js +9 -8
  205. package/slicing/static/static-slicer.js +24 -1
  206. package/util/collections/arrays.d.ts +4 -0
  207. package/util/collections/arrays.js +7 -0
  208. package/util/mermaid/ast.js +2 -1
  209. package/util/mermaid/dfg.js +2 -1
  210. package/util/record.d.ts +23 -0
  211. package/util/record.js +33 -0
  212. package/util/version.js +1 -1
  213. package/abstract-interpretation/domains/mapped-abstract-domain.d.ts +0 -41
  214. package/abstract-interpretation/domains/mapped-abstract-domain.js +0 -213
@@ -68,18 +68,48 @@ exports.FunctionArgument = {
68
68
  return arg !== r_function_call_1.EmptyArgument;
69
69
  },
70
70
  /**
71
- * Returns the reference of a non-empty argument.
71
+ * Returns the id of a non-empty argument.
72
72
  * @example
73
73
  * ```r
74
- * foo(a=3, 2) # returns the node id of either `3` or `2`, but skips a
74
+ * foo(a=3, 2) # returns the node id of either `a` or `2`
75
75
  * ```
76
+ * @see {@link FunctionArgument.getReference}
77
+ * @see {@link FunctionArgument.getName}
76
78
  */
77
- getReference(arg) {
79
+ getId(arg) {
78
80
  if (arg !== r_function_call_1.EmptyArgument) {
79
81
  return arg?.nodeId;
80
82
  }
81
83
  return undefined;
82
84
  },
85
+ /**
86
+ * Returns the name of a named argument.
87
+ * @example
88
+ * ```r
89
+ * foo(a = 3, 2) # returns 'a' or undefined
90
+ * ```
91
+ * @see {@link FunctionArgument.getId}
92
+ */
93
+ getName(arg) {
94
+ return exports.FunctionArgument.isNamed(arg) ? arg.name : undefined;
95
+ },
96
+ /**
97
+ * Returns the reference of a non-empty argument.
98
+ * @example
99
+ * ```r
100
+ * foo(a=3, 2) # returns the node id of either `3` or `2`, but skips a
101
+ * ```
102
+ * @see {@link FunctionArgument.getId}
103
+ */
104
+ getReference(arg) {
105
+ if (arg === r_function_call_1.EmptyArgument) {
106
+ return undefined;
107
+ }
108
+ else if (arg.name === undefined) {
109
+ return arg.nodeId;
110
+ }
111
+ return arg.valueId;
112
+ },
83
113
  /**
84
114
  * Checks whether the given argument is a named argument with the specified name.
85
115
  * Please note that this only checks whether the name is exactly identical and not whether
@@ -369,8 +399,9 @@ class DataflowGraph {
369
399
  /**
370
400
  * Marks a vertex in the graph to be a definition
371
401
  * @param reference - The reference to the vertex to mark as definition
402
+ * @param sourceIds - The id of the source vertex of the def, if available
372
403
  */
373
- setDefinitionOfVertex(reference) {
404
+ setDefinitionOfVertex(reference, sourceIds) {
374
405
  const vertex = this.getVertex(reference.nodeId);
375
406
  (0, assert_1.guard)(vertex !== undefined, () => `node must be defined for ${JSON.stringify(reference)} to set reference`);
376
407
  if (vertex.tag === vertex_1.VertexType.FunctionDefinition || vertex.tag === vertex_1.VertexType.VariableDefinition) {
@@ -379,6 +410,9 @@ class DataflowGraph {
379
410
  else {
380
411
  const oldTag = vertex.tag;
381
412
  vertex.tag = vertex_1.VertexType.VariableDefinition;
413
+ if (sourceIds) {
414
+ vertex.source = sourceIds;
415
+ }
382
416
  this.types.set(oldTag, (this.types.get(oldTag) ?? []).filter(id => id !== reference.nodeId));
383
417
  this.types.set(vertex_1.VertexType.VariableDefinition, (this.types.get(vertex_1.VertexType.VariableDefinition) ?? []).concat([reference.nodeId]));
384
418
  }
@@ -123,6 +123,8 @@ export interface DataflowGraphVertexVariableDefinition extends DataflowGraphVert
123
123
  readonly environment?: undefined;
124
124
  /** Indicates whether the variable definition is a *partial* definition (e.g,. in `x[a] <- b`) */
125
125
  readonly par?: true;
126
+ /** Points to the source ids of the "value" if there is one, this is more of a best-effort flag and not guaranteed to be there */
127
+ readonly source?: readonly NodeId[];
126
128
  }
127
129
  /**
128
130
  * Arguments required to construct a vertex which represents the definition of a function in the {@link DataflowGraph|dataflow graph}.
@@ -5,5 +5,15 @@ import type { RType } from '../../r-bridge/lang-4.x/ast/model/type';
5
5
  /**
6
6
  * This takes the out parameter `countMap` and fills it with the count of how many times each RType was processed.
7
7
  * The accompanying `reset` function can be used to reset the map to an empty state.
8
+ * @example
9
+ * ```ts
10
+ * const map = new Map<RType, number>();
11
+ * const analyzer = await new FlowrAnalyzerBuilder()
12
+ * .configure('solver.instrument.dataflowExtractors', instrumentDataflowCount(map, () => map.clear()))
13
+ * .build();
14
+ * analyzer.addRequest(requestFromInput(code));
15
+ * await analyzer.dataflow();
16
+ * ```
17
+ * Now, you can inspect the counts in the `map` objects, these will be reset for each new analysis request using the `() => map.clear()` function.
8
18
  */
9
19
  export declare function instrumentDataflowCount(countMap: Map<RType, number>, reset: (map: Map<RType, number>) => void): (extractor: DataflowProcessors<ParentInformation>, ctx: FlowrAnalyzerContext) => DataflowProcessors<ParentInformation>;
@@ -4,6 +4,16 @@ exports.instrumentDataflowCount = instrumentDataflowCount;
4
4
  /**
5
5
  * This takes the out parameter `countMap` and fills it with the count of how many times each RType was processed.
6
6
  * The accompanying `reset` function can be used to reset the map to an empty state.
7
+ * @example
8
+ * ```ts
9
+ * const map = new Map<RType, number>();
10
+ * const analyzer = await new FlowrAnalyzerBuilder()
11
+ * .configure('solver.instrument.dataflowExtractors', instrumentDataflowCount(map, () => map.clear()))
12
+ * .build();
13
+ * analyzer.addRequest(requestFromInput(code));
14
+ * await analyzer.dataflow();
15
+ * ```
16
+ * Now, you can inspect the counts in the `map` objects, these will be reset for each new analysis request using the `() => map.clear()` function.
7
17
  */
8
18
  function instrumentDataflowCount(countMap, reset) {
9
19
  return (extractor, _ctx) => {
@@ -1,16 +1,16 @@
1
- import { type RFunctionArgument } from '../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-function-call';
1
+ import { type PotentiallyEmptyRArgument } from '../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-function-call';
2
2
  import type { RNode } from '../../../../../../r-bridge/lang-4.x/ast/model/model';
3
3
  /**
4
4
  * Retrieve the value from an argument, if it is not empty.
5
5
  * @see {@link unpackArg} - to specifically retrieve non-named arguments
6
6
  */
7
- export declare function unpackNonameArg<OtherInfo>(arg: RFunctionArgument<OtherInfo> | undefined): RNode<OtherInfo> | undefined;
7
+ export declare function unpackNonameArg<OtherInfo>(arg: PotentiallyEmptyRArgument<OtherInfo> | undefined): RNode<OtherInfo> | undefined;
8
8
  /**
9
9
  * Retrieve the value from a non-named argument, if it is not empty.
10
10
  * @see {@link unpackNonameArg} - to specifically retrieve non-named arguments
11
11
  */
12
- export declare function unpackArg<OtherInfo>(arg: RFunctionArgument<OtherInfo> | undefined): RNode<OtherInfo> | undefined;
12
+ export declare function unpackArg<OtherInfo>(arg: PotentiallyEmptyRArgument<OtherInfo> | undefined): RNode<OtherInfo> | undefined;
13
13
  /**
14
14
  * Try to unpack the given argument, if it is not empty.
15
15
  */
16
- export declare function tryUnpackNoNameArg<OtherInfo>(arg: RFunctionArgument<OtherInfo>): RNode<OtherInfo> | RFunctionArgument<OtherInfo>;
16
+ export declare function tryUnpackNoNameArg<OtherInfo>(arg: PotentiallyEmptyRArgument<OtherInfo>): RNode<OtherInfo> | PotentiallyEmptyRArgument<OtherInfo>;
@@ -1,7 +1,7 @@
1
1
  import type { DataflowProcessorInformation } from '../../../../../processor';
2
2
  import type { DataflowInformation } from '../../../../../info';
3
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';
4
+ import { type PotentiallyEmptyRArgument } 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 { NodeId } from '../../../../../../r-bridge/lang-4.x/ast/model/processing/node-id';
7
7
  import type { ForceArguments } from '../common';
@@ -16,10 +16,10 @@ import type { ForceArguments } from '../common';
16
16
  * a@foo
17
17
  * ```
18
18
  */
19
- export declare function processAccess<OtherInfo>(name: RSymbol<OtherInfo & ParentInformation>, args: readonly RFunctionArgument<OtherInfo & ParentInformation>[], rootId: NodeId, data: DataflowProcessorInformation<OtherInfo & ParentInformation>, config: {
19
+ export declare function processAccess<OtherInfo>(name: RSymbol<OtherInfo & ParentInformation>, args: readonly PotentiallyEmptyRArgument<OtherInfo & ParentInformation>[], rootId: NodeId, data: DataflowProcessorInformation<OtherInfo & ParentInformation>, config: {
20
20
  treatIndicesAsString: boolean;
21
21
  } & ForceArguments): DataflowInformation;
22
22
  /**
23
23
  * Converts symbol arguments to string arguments within the specified range.
24
24
  */
25
- export declare function symbolArgumentsToStrings<OtherInfo>(args: readonly RFunctionArgument<OtherInfo & ParentInformation>[], firstIndexInclusive?: number, lastIndexInclusive?: number): RFunctionArgument<OtherInfo & ParentInformation>[];
25
+ export declare function symbolArgumentsToStrings<OtherInfo>(args: readonly PotentiallyEmptyRArgument<OtherInfo & ParentInformation>[], firstIndexInclusive?: number, lastIndexInclusive?: number): PotentiallyEmptyRArgument<OtherInfo & ParentInformation>[];
@@ -1,6 +1,6 @@
1
1
  import type { DataflowProcessorInformation } from '../../../../../processor';
2
2
  import type { DataflowInformation } from '../../../../../info';
3
- import { type RFunctionArgument } from '../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-function-call';
3
+ import { type PotentiallyEmptyRArgument } 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
  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';
@@ -20,4 +20,4 @@ export interface BuiltInApplyConfiguration extends MergeableRecord {
20
20
  /**
21
21
  * Process an apply call like `vapply` or `mapply`.
22
22
  */
23
- export declare function processApply<OtherInfo>(name: RSymbol<OtherInfo & ParentInformation>, args: readonly RFunctionArgument<OtherInfo & ParentInformation>[], rootId: NodeId, data: DataflowProcessorInformation<OtherInfo & ParentInformation>, config: BuiltInApplyConfiguration): DataflowInformation;
23
+ export declare function processApply<OtherInfo>(name: RSymbol<OtherInfo & ParentInformation>, args: readonly PotentiallyEmptyRArgument<OtherInfo & ParentInformation>[], rootId: NodeId, data: DataflowProcessorInformation<OtherInfo & ParentInformation>, config: BuiltInApplyConfiguration): DataflowInformation;
@@ -98,6 +98,7 @@ function processApply(name, args, rootId, data, config) {
98
98
  if (arg && counterpart !== r_function_call_1.EmptyArgument) {
99
99
  return {
100
100
  name: counterpart.name?.content,
101
+ valueId: counterpart.value?.info.id,
101
102
  cds: data.cds,
102
103
  type: identifier_1.ReferenceType.Argument,
103
104
  nodeId: arg.entryPoint
@@ -3,7 +3,7 @@ import type { DataflowInformation } from '../../../../../info';
3
3
  import type { ParentInformation } from '../../../../../../r-bridge/lang-4.x/ast/model/processing/decorate';
4
4
  import type { RNode } from '../../../../../../r-bridge/lang-4.x/ast/model/model';
5
5
  import type { RSymbol } from '../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-symbol';
6
- import type { RFunctionArgument } from '../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-function-call';
6
+ import type { PotentiallyEmptyRArgument } from '../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-function-call';
7
7
  import { type NodeId } from '../../../../../../r-bridge/lang-4.x/ast/model/processing/node-id';
8
8
  import { Identifier, type InGraphIdentifierDefinition } from '../../../../../environments/identifier';
9
9
  import type { DataflowGraphVertexFunctionDefinition } from '../../../../../graph/vertex';
@@ -35,13 +35,13 @@ export interface ExtendedAssignmentConfiguration extends AssignmentConfiguration
35
35
  /**
36
36
  * In contrast to `processAssignment`, this function allows more flexible handling of assignment-like functions.
37
37
  */
38
- export declare function processAssignmentLike<OtherInfo>(name: RSymbol<OtherInfo & ParentInformation>, args: readonly RFunctionArgument<OtherInfo & ParentInformation>[], rootId: NodeId, data: DataflowProcessorInformation<OtherInfo & ParentInformation>, config: ExtendedAssignmentConfiguration): DataflowInformation;
38
+ export declare function processAssignmentLike<OtherInfo>(name: RSymbol<OtherInfo & ParentInformation>, args: readonly PotentiallyEmptyRArgument<OtherInfo & ParentInformation>[], rootId: NodeId, data: DataflowProcessorInformation<OtherInfo & ParentInformation>, config: ExtendedAssignmentConfiguration): DataflowInformation;
39
39
  /**
40
40
  * Processes an assignment, i.e., `<target> <- <source>`.
41
41
  * Handling it as a function call \`&lt;-\` `(<target>, <source>)`.
42
42
  * This includes handling of replacement functions (e.g., `names(x) <- ...` as \`names&lt;-\` `(x, ...)`).
43
43
  */
44
- export declare function processAssignment<OtherInfo>(name: RSymbol<OtherInfo & ParentInformation>, args: readonly RFunctionArgument<OtherInfo & ParentInformation>[], rootId: NodeId, data: DataflowProcessorInformation<OtherInfo & ParentInformation>, config: AssignmentConfiguration): DataflowInformation;
44
+ export declare function processAssignment<OtherInfo>(name: RSymbol<OtherInfo & ParentInformation>, args: readonly PotentiallyEmptyRArgument<OtherInfo & ParentInformation>[], rootId: NodeId, data: DataflowProcessorInformation<OtherInfo & ParentInformation>, config: AssignmentConfiguration): DataflowInformation;
45
45
  export interface AssignmentToSymbolParameters<OtherInfo> extends AssignmentConfiguration {
46
46
  readonly nameOfAssignmentFunction: Identifier;
47
47
  readonly source: RNode<OtherInfo & ParentInformation>;
@@ -297,7 +297,7 @@ function checkTargetReferenceType(sourceInfo, fnModes) {
297
297
  */
298
298
  function markAsAssignment(information, nodeToDefine, sourceIds, rootIdOfAssignment, data, assignmentConfig) {
299
299
  information.environment = (0, define_1.define)(nodeToDefine, assignmentConfig?.superAssignment, information.environment);
300
- information.graph.setDefinitionOfVertex(nodeToDefine);
300
+ information.graph.setDefinitionOfVertex(nodeToDefine, sourceIds);
301
301
  const nid = nodeToDefine.nodeId;
302
302
  if (!assignmentConfig?.quoteSource) {
303
303
  for (const sourceId of sourceIds) {
@@ -1,13 +1,13 @@
1
1
  import { type DataflowProcessorInformation } from '../../../../../processor';
2
2
  import { DataflowInformation } from '../../../../../info';
3
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';
4
+ import { type PotentiallyEmptyRArgument } 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
7
  /**
8
8
  * Process a call to `eval()`, trying to resolve the code being evaluated if possible.
9
9
  */
10
- export declare function processEvalCall<OtherInfo>(name: RSymbol<OtherInfo & ParentInformation>, args: readonly RFunctionArgument<OtherInfo & ParentInformation>[], rootId: NodeId, data: DataflowProcessorInformation<OtherInfo & ParentInformation>, config: {
10
+ export declare function processEvalCall<OtherInfo>(name: RSymbol<OtherInfo & ParentInformation>, args: readonly PotentiallyEmptyRArgument<OtherInfo & ParentInformation>[], rootId: NodeId, data: DataflowProcessorInformation<OtherInfo & ParentInformation>, config: {
11
11
  /** should this produce an explicit source function call in the graph? */
12
12
  includeFunctionCall?: boolean;
13
13
  }): DataflowInformation;
@@ -6,9 +6,9 @@ import type { DataflowInformation } from '../../../../../info';
6
6
  import { type DataflowProcessorInformation } from '../../../../../processor';
7
7
  import { NodeId } from '../../../../../../r-bridge/lang-4.x/ast/model/processing/node-id';
8
8
  import type { ParentInformation } from '../../../../../../r-bridge/lang-4.x/ast/model/processing/decorate';
9
- import type { RFunctionArgument } from '../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-function-call';
9
+ import type { PotentiallyEmptyRArgument } from '../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-function-call';
10
10
  import type { RSymbol } from '../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-symbol';
11
11
  /**
12
12
  * Processes a list of expressions joining their dataflow graphs accordingly.
13
13
  */
14
- export declare function processExpressionList<OtherInfo>(name: RSymbol<OtherInfo & ParentInformation>, args: readonly RFunctionArgument<OtherInfo & ParentInformation>[], rootId: NodeId, data: DataflowProcessorInformation<OtherInfo & ParentInformation>): DataflowInformation;
14
+ export declare function processExpressionList<OtherInfo>(name: RSymbol<OtherInfo & ParentInformation>, args: readonly PotentiallyEmptyRArgument<OtherInfo & ParentInformation>[], rootId: NodeId, data: DataflowProcessorInformation<OtherInfo & ParentInformation>): DataflowInformation;
@@ -1,7 +1,7 @@
1
1
  import { type DataflowProcessorInformation } from '../../../../../processor';
2
2
  import { type DataflowInformation } from '../../../../../info';
3
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';
4
+ import type { PotentiallyEmptyRArgument } from '../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-function-call';
5
5
  import type { NodeId } from '../../../../../../r-bridge/lang-4.x/ast/model/processing/node-id';
6
6
  import type { RSymbol } from '../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-symbol';
7
7
  /**
@@ -11,4 +11,4 @@ import type { RSymbol } from '../../../../../../r-bridge/lang-4.x/ast/model/node
11
11
  * `for`(<variable>, <vector>, <body>)
12
12
  * ```
13
13
  */
14
- export declare function processForLoop<OtherInfo>(name: RSymbol<OtherInfo & ParentInformation>, args: readonly RFunctionArgument<OtherInfo & ParentInformation>[], rootId: NodeId, data: DataflowProcessorInformation<OtherInfo & ParentInformation>): DataflowInformation;
14
+ export declare function processForLoop<OtherInfo>(name: RSymbol<OtherInfo & ParentInformation>, args: readonly PotentiallyEmptyRArgument<OtherInfo & ParentInformation>[], rootId: NodeId, data: DataflowProcessorInformation<OtherInfo & ParentInformation>): DataflowInformation;
@@ -60,7 +60,7 @@ function processForLoop(name, args, rootId, data) {
60
60
  const nameIdShares = (0, linker_1.produceNameSharedIdMap)((0, linker_1.findNonLocalReads)(nextGraph, writtenIds));
61
61
  for (const write of writtenVariable) {
62
62
  nextGraph.addEdge(write.nodeId, vector.entryPoint, edge_1.EdgeType.DefinedBy);
63
- nextGraph.setDefinitionOfVertex(write);
63
+ nextGraph.setDefinitionOfVertex(write, [vector.entryPoint]);
64
64
  }
65
65
  (0, reference_to_maybe_1.applyCdToReferences)(body.out, cd);
66
66
  const outgoing = variable.out.concat(writtenVariable, body.out);
@@ -2,7 +2,7 @@ import { type DataflowProcessorInformation } from '../../../../../processor';
2
2
  import { type DataflowInformation } from '../../../../../info';
3
3
  import type { ParentInformation } from '../../../../../../r-bridge/lang-4.x/ast/model/processing/decorate';
4
4
  import type { RSymbol } from '../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-symbol';
5
- import { type RFunctionArgument } from '../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-function-call';
5
+ import { type PotentiallyEmptyRArgument } from '../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-function-call';
6
6
  import { NodeId } from '../../../../../../r-bridge/lang-4.x/ast/model/processing/node-id';
7
7
  import { DataflowGraph } from '../../../../../graph/graph';
8
8
  import { type REnvironmentInformation } from '../../../../../environments/environment';
@@ -10,7 +10,7 @@ import type { ReadOnlyFlowrAnalyzerContext } from '../../../../../../project/con
10
10
  /**
11
11
  * Process a function definition, i.e., `function(a, b) { ... }`
12
12
  */
13
- export declare function processFunctionDefinition<OtherInfo>(name: RSymbol<OtherInfo & ParentInformation>, args: readonly RFunctionArgument<OtherInfo & ParentInformation>[], rootId: NodeId, data: DataflowProcessorInformation<OtherInfo & ParentInformation>): DataflowInformation;
13
+ export declare function processFunctionDefinition<OtherInfo>(name: RSymbol<OtherInfo & ParentInformation>, args: readonly PotentiallyEmptyRArgument<OtherInfo & ParentInformation>[], rootId: NodeId, data: DataflowProcessorInformation<OtherInfo & ParentInformation>): DataflowInformation;
14
14
  /**
15
15
  * Retrieve the active environment when entering a function definition or call
16
16
  * @param callerEnvironment - environment at the call site / function definition site
@@ -99,10 +99,10 @@ function processFunctionDefinition(name, args, rootId, data) {
99
99
  return r_function_call_1.EmptyArgument;
100
100
  }
101
101
  else if (!p.name && p.value && p.value.type === type_1.RType.Parameter) {
102
- return { type: identifier_1.ReferenceType.Argument, cds: data.cds, nodeId: p.value.name.info.id, name: p.value.name.content };
102
+ return { type: identifier_1.ReferenceType.Argument, cds: data.cds, nodeId: p.value.name.info.id, name: p.value.name.content, valueId: p.value.defaultValue?.info.id };
103
103
  }
104
104
  else if (p.name) {
105
- return { type: identifier_1.ReferenceType.Argument, cds: data.cds, nodeId: p.name.info.id, name: p.name.content };
105
+ return { type: identifier_1.ReferenceType.Argument, valueId: p.value?.info.id, cds: data.cds, nodeId: p.name.info.id, name: p.name.content };
106
106
  }
107
107
  else {
108
108
  return r_function_call_1.EmptyArgument;
@@ -231,20 +231,10 @@ function updateNestedFunctionCalls(graph, outEnvironment) {
231
231
  // track *all* function definitions - including those nested within the current graph,
232
232
  // try to resolve their 'in' by only using the lowest scope which will be popped after this definition
233
233
  for (const [id, { onlyBuiltin, environment, name, args, origin }] of graph.verticesOfType(vertex_1.VertexType.FunctionCall)) {
234
- if (onlyBuiltin || !name) {
234
+ if (onlyBuiltin || name === undefined) {
235
235
  continue;
236
236
  }
237
- let effectiveEnvironment = outEnvironment;
238
- // only the call environment counts!
239
- if (environment) {
240
- while (outEnvironment.level > environment.level) {
241
- outEnvironment = (0, scoping_1.popLocalEnvironment)(outEnvironment);
242
- }
243
- while (outEnvironment.level < environment.level) {
244
- outEnvironment = (0, scoping_1.pushLocalEnvironment)(outEnvironment);
245
- }
246
- effectiveEnvironment = (0, overwrite_1.overwriteEnvironment)(outEnvironment, environment);
247
- }
237
+ const effectiveEnvironment = environment ? (0, overwrite_1.overwriteEnvironment)(outEnvironment, environment) : outEnvironment;
248
238
  const targets = new Set((0, linker_1.getAllFunctionCallTargets)(id, graph, effectiveEnvironment));
249
239
  const collectedNextMethods = new Set();
250
240
  const treatAsS3 = origin.includes(built_in_proc_name_1.BuiltInProcName.S3Dispatch);
@@ -255,11 +245,10 @@ function updateNestedFunctionCalls(graph, outEnvironment) {
255
245
  }
256
246
  const targetVertex = graph.getVertex(target);
257
247
  // support reads on symbols
258
- if (targetVertex?.tag === vertex_1.VertexType.Use) {
259
- graph.addEdge(id, target, edge_1.EdgeType.Reads);
260
- continue;
261
- }
262
- else if (targetVertex?.tag !== vertex_1.VertexType.FunctionDefinition) {
248
+ if (targetVertex?.tag !== vertex_1.VertexType.FunctionDefinition) {
249
+ if (targetVertex?.tag === vertex_1.VertexType.Use) {
250
+ graph.addEdge(id, target, edge_1.EdgeType.Reads);
251
+ }
263
252
  continue;
264
253
  }
265
254
  graph.addEdge(id, target, edge_1.EdgeType.Calls);
@@ -1,10 +1,10 @@
1
1
  import type { DataflowProcessorInformation } from '../../../../../processor';
2
2
  import type { DataflowInformation } from '../../../../../info';
3
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';
4
+ import type { PotentiallyEmptyRArgument } 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
7
  /**
8
8
  * Processes a built-in 'get' function call.
9
9
  */
10
- export declare function processGet<OtherInfo>(name: RSymbol<OtherInfo & ParentInformation>, args: readonly RFunctionArgument<OtherInfo & ParentInformation>[], rootId: NodeId, data: DataflowProcessorInformation<OtherInfo & ParentInformation>): DataflowInformation;
10
+ export declare function processGet<OtherInfo>(name: RSymbol<OtherInfo & ParentInformation>, args: readonly PotentiallyEmptyRArgument<OtherInfo & ParentInformation>[], rootId: NodeId, data: DataflowProcessorInformation<OtherInfo & ParentInformation>): DataflowInformation;
@@ -2,7 +2,7 @@ import { type DataflowProcessorInformation } from '../../../../../processor';
2
2
  import { type DataflowInformation } from '../../../../../info';
3
3
  import type { RSymbol } from '../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-symbol';
4
4
  import type { ParentInformation } from '../../../../../../r-bridge/lang-4.x/ast/model/processing/decorate';
5
- import type { RFunctionArgument } from '../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-function-call';
5
+ import type { PotentiallyEmptyRArgument } from '../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-function-call';
6
6
  import type { NodeId } from '../../../../../../r-bridge/lang-4.x/ast/model/processing/node-id';
7
7
  /** `if(<cond>) <then> else <else>` built-in function configuration, make sure to not reuse indices */
8
8
  export interface IfThenElseConfig {
@@ -20,4 +20,4 @@ export interface IfThenElseConfig {
20
20
  * For example, `if(cond) thenExpr else elseExpr` and `if(cond) thenExpr`.
21
21
  * The arguments will be either `[cond, thenExpr]` or `[cond, thenExpr, elseExpr]`.
22
22
  */
23
- export declare function processIfThenElse<OtherInfo>(name: RSymbol<OtherInfo & ParentInformation>, args: readonly RFunctionArgument<OtherInfo & ParentInformation>[], rootId: NodeId, data: DataflowProcessorInformation<OtherInfo & ParentInformation>, config?: IfThenElseConfig): DataflowInformation;
23
+ export declare function processIfThenElse<OtherInfo>(name: RSymbol<OtherInfo & ParentInformation>, args: readonly PotentiallyEmptyRArgument<OtherInfo & ParentInformation>[], rootId: NodeId, data: DataflowProcessorInformation<OtherInfo & ParentInformation>, config?: IfThenElseConfig): DataflowInformation;
@@ -1,10 +1,10 @@
1
1
  import { type DataflowProcessorInformation } from '../../../../../processor';
2
2
  import type { DataflowInformation } from '../../../../../info';
3
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';
4
+ import type { PotentiallyEmptyRArgument } 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
7
  /**
8
8
  * Process a library call like `library` or `require`
9
9
  */
10
- export declare function processLibrary<OtherInfo>(name: RSymbol<OtherInfo & ParentInformation>, args: readonly RFunctionArgument<OtherInfo & ParentInformation>[], rootId: NodeId, data: DataflowProcessorInformation<OtherInfo & ParentInformation>): DataflowInformation;
10
+ export declare function processLibrary<OtherInfo>(name: RSymbol<OtherInfo & ParentInformation>, args: readonly PotentiallyEmptyRArgument<OtherInfo & ParentInformation>[], rootId: NodeId, data: DataflowProcessorInformation<OtherInfo & ParentInformation>): DataflowInformation;
@@ -1,4 +1,4 @@
1
- import { type RFunctionArgument } from '../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-function-call';
1
+ import { type PotentiallyEmptyRArgument } from '../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-function-call';
2
2
  import type { RSymbol } from '../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-symbol';
3
3
  import type { ParentInformation } from '../../../../../../r-bridge/lang-4.x/ast/model/processing/decorate';
4
4
  import type { NodeId } from '../../../../../../r-bridge/lang-4.x/ast/model/processing/node-id';
@@ -12,4 +12,4 @@ import type { DataflowProcessorInformation } from '../../../../../processor';
12
12
  * list(a = 1, b = 2)
13
13
  * ```
14
14
  */
15
- export declare function processList<OtherInfo>(name: RSymbol<OtherInfo & ParentInformation>, args: readonly RFunctionArgument<OtherInfo & ParentInformation>[], rootId: NodeId, data: DataflowProcessorInformation<OtherInfo & ParentInformation>): DataflowInformation;
15
+ export declare function processList<OtherInfo>(name: RSymbol<OtherInfo & ParentInformation>, args: readonly PotentiallyEmptyRArgument<OtherInfo & ParentInformation>[], rootId: NodeId, data: DataflowProcessorInformation<OtherInfo & ParentInformation>): DataflowInformation;
@@ -1,7 +1,7 @@
1
1
  import type { DataflowProcessorInformation } from '../../../../../processor';
2
2
  import { DataflowInformation } from '../../../../../info';
3
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';
4
+ import type { PotentiallyEmptyRArgument } 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
7
  export interface LocalFunctionConfiguration {
@@ -15,4 +15,4 @@ export interface LocalFunctionConfiguration {
15
15
  /**
16
16
  * Processes a built-in 'local' function call.
17
17
  */
18
- export declare function processLocal<OtherInfo>(name: RSymbol<OtherInfo & ParentInformation>, args: readonly RFunctionArgument<OtherInfo & ParentInformation>[], rootId: NodeId, data: DataflowProcessorInformation<OtherInfo & ParentInformation>, config: LocalFunctionConfiguration): DataflowInformation;
18
+ export declare function processLocal<OtherInfo>(name: RSymbol<OtherInfo & ParentInformation>, args: readonly PotentiallyEmptyRArgument<OtherInfo & ParentInformation>[], rootId: NodeId, data: DataflowProcessorInformation<OtherInfo & ParentInformation>, config: LocalFunctionConfiguration): DataflowInformation;
@@ -1,10 +1,30 @@
1
1
  import type { DataflowProcessorInformation } from '../../../../../processor';
2
2
  import type { DataflowInformation } from '../../../../../info';
3
- import type { RFunctionArgument } from '../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-function-call';
3
+ import type { PotentiallyEmptyRArgument } 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
  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 { BrandedIdentifier } from '../../../../../environments/identifier';
7
8
  /**
8
- * Suport for R's pipe functions like `|>`.
9
+ * Configuration options for the basic R pipe
9
10
  */
10
- export declare function processPipe<OtherInfo>(name: RSymbol<OtherInfo & ParentInformation>, args: readonly RFunctionArgument<OtherInfo & ParentInformation>[], rootId: NodeId, data: DataflowProcessorInformation<OtherInfo & ParentInformation>): DataflowInformation;
11
+ interface PipeConfiguration {
12
+ pipePlaceholderName: BrandedIdentifier;
13
+ /**
14
+ * this is for a pipe like `%<>%` which assigns its lhs
15
+ */
16
+ assignLhs: boolean;
17
+ /**
18
+ * Whether to return the lhs (e.g., with the TPipe)
19
+ */
20
+ returnLhs: boolean;
21
+ /**
22
+ * If so, also allow a symbol instead of a function as rhs, if it is the case, this automatically converts the symbol on the rhs to a function call
23
+ */
24
+ rhsMightBeSymbol?: boolean;
25
+ }
26
+ /**
27
+ * Support for R's pipe functions like `|>` or magrittr's `%>%`
28
+ */
29
+ export declare function processPipe<OtherInfo>(name: RSymbol<OtherInfo & ParentInformation>, args: readonly PotentiallyEmptyRArgument<OtherInfo & ParentInformation>[], rootId: NodeId, data: DataflowProcessorInformation<OtherInfo & ParentInformation>, { pipePlaceholderName, assignLhs, returnLhs, rhsMightBeSymbol }: PipeConfiguration): DataflowInformation;
30
+ export {};
@@ -4,41 +4,109 @@ exports.processPipe = processPipe;
4
4
  const known_call_handling_1 = require("../known-call-handling");
5
5
  const assert_1 = require("../../../../../../util/assert");
6
6
  const unpack_argument_1 = require("../argument/unpack-argument");
7
+ const model_1 = require("../../../../../../r-bridge/lang-4.x/ast/model/model");
7
8
  const logger_1 = require("../../../../../logger");
8
9
  const type_1 = require("../../../../../../r-bridge/lang-4.x/ast/model/type");
9
10
  const vertex_1 = require("../../../../../graph/vertex");
10
11
  const edge_1 = require("../../../../../graph/edge");
11
12
  const identifier_1 = require("../../../../../environments/identifier");
13
+ const make_argument_1 = require("../argument/make-argument");
14
+ const built_in_assignment_1 = require("./built-in-assignment");
12
15
  const built_in_proc_name_1 = require("../../../../../environments/built-in-proc-name");
16
+ const log_1 = require("../../../../../../util/log");
13
17
  /**
14
- * Suport for R's pipe functions like `|>`.
18
+ * Support for R's pipe functions like `|>` or magrittr's `%>%`
15
19
  */
16
- function processPipe(name, args, rootId, data) {
17
- const { information, processedArguments } = (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data, origin: built_in_proc_name_1.BuiltInProcName.Pipe });
20
+ function processPipe(name, args, rootId, data, { pipePlaceholderName, assignLhs, returnLhs, rhsMightBeSymbol = false }) {
21
+ const fCallInfo = (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data, origin: built_in_proc_name_1.BuiltInProcName.Pipe });
22
+ const processedArguments = fCallInfo.processedArguments;
23
+ let information = fCallInfo.information;
18
24
  if (args.length !== 2) {
19
25
  logger_1.dataflowLogger.warn(`Pipe ${identifier_1.Identifier.toString(name.content)} has something else than 2 arguments, skipping`);
20
26
  return information;
21
27
  }
22
28
  const [lhs, rhs] = args.map(e => (0, unpack_argument_1.unpackNonameArg)(e));
23
29
  (0, assert_1.guard)(lhs !== undefined && rhs !== undefined, () => `lhs and rhs must be present, but ${JSON.stringify(lhs)} and ${JSON.stringify(rhs)} were found instead.`);
24
- if (rhs.type === type_1.RType.FunctionCall) {
30
+ // If this is an assigning pipe (e.g., %<>%), perform the assignment writeback using the built-in
31
+ // assignment processor: target <- source where target is the original lhs and source is the rhs call
32
+ if (assignLhs) {
33
+ // create unnamed args for target and source
34
+ const targetArg = (0, make_argument_1.toUnnamedArgument)(lhs, data.completeAst.idMap);
35
+ const sourceArg = (0, make_argument_1.toUnnamedArgument)(rhs, data.completeAst.idMap);
36
+ // construct a synthetic symbol for the assignment operator '<-'
37
+ const assignSym = {
38
+ type: type_1.RType.Symbol,
39
+ info: name.info,
40
+ content: identifier_1.Identifier.make('<-', 'base'),
41
+ lexeme: '<-',
42
+ location: name.location
43
+ };
44
+ information = (0, built_in_assignment_1.processAssignment)(assignSym, [targetArg, sourceArg], rootId, data, { canBeReplacement: true, mayHaveMoreArgs: true });
45
+ }
46
+ let treatedAsFunctionCall = false;
47
+ if (rhs.type === type_1.RType.Symbol && rhsMightBeSymbol) {
48
+ // convert a plain symbol on the RHS into a function-call vertex so we can treat it like `df %>% head`
49
+ const maybeVertex = information.graph.getVertex(rhs.info.id);
50
+ if (maybeVertex && maybeVertex.tag === vertex_1.VertexType.Use) {
51
+ information.graph.updateToFunctionCall({
52
+ tag: vertex_1.VertexType.FunctionCall,
53
+ id: rhs.info.id,
54
+ name: rhs.content,
55
+ args: [],
56
+ environment: data.environment,
57
+ onlyBuiltin: false,
58
+ cds: data.cds,
59
+ origin: [built_in_proc_name_1.BuiltInProcName.Function]
60
+ });
61
+ treatedAsFunctionCall = true;
62
+ }
63
+ }
64
+ if (treatedAsFunctionCall || rhs.type === type_1.RType.FunctionCall) {
25
65
  const functionCallNode = information.graph.getVertex(rhs.info.id);
26
66
  (0, assert_1.guard)(functionCallNode?.tag === vertex_1.VertexType.FunctionCall, () => `Expected function call node with id ${rhs.info.id} to be a function call node, but got ${functionCallNode?.tag} instead.`);
27
- // make the lhs an argument node:
67
+ // make the lhs an argument node (or link it to placeholders within the rhs call):
28
68
  const argId = lhs.info.id;
29
- logger_1.dataflowLogger.trace(`Linking pipe arg ${argId} as first argument of ${rhs.info.id}`);
30
- functionCallNode.args.unshift({
31
- name: undefined,
32
- nodeId: argId,
33
- cds: data.cds,
34
- type: identifier_1.ReferenceType.Function
69
+ // find all symbol occurrences inside the rhs function call AST that match the placeholder name
70
+ const occurrenceIds = [];
71
+ model_1.RNode.visitAst(rhs, (node) => {
72
+ if (node.type === type_1.RType.Symbol && node.content === pipePlaceholderName) {
73
+ occurrenceIds.push(node.info.id);
74
+ }
75
+ return false;
35
76
  });
36
- information.graph.addEdge(functionCallNode.id, argId, edge_1.EdgeType.Argument | edge_1.EdgeType.Reads);
77
+ if (occurrenceIds.length > 0) {
78
+ if (occurrenceIds.length !== 1) {
79
+ log_1.log.warn(`Expected exactly one occurrence of the pipe placeholder '${identifier_1.Identifier.toString(pipePlaceholderName)}' in the rhs of the pipe, but found ${occurrenceIds.length}. Linking all occurrences to the lhs.`);
80
+ }
81
+ for (const occId of occurrenceIds) {
82
+ information.graph.addEdge(occId, argId, edge_1.EdgeType.Reads);
83
+ }
84
+ }
85
+ else {
86
+ logger_1.dataflowLogger.trace(`Linking pipe arg ${argId} as first argument of ${rhs.info.id}`);
87
+ functionCallNode.args.unshift({
88
+ name: undefined,
89
+ nodeId: argId,
90
+ cds: data.cds,
91
+ type: identifier_1.ReferenceType.Function
92
+ });
93
+ information.graph.addEdge(functionCallNode.id, argId, edge_1.EdgeType.Argument | edge_1.EdgeType.Reads);
94
+ }
37
95
  }
38
96
  else {
39
97
  logger_1.dataflowLogger.warn(`Expected rhs of pipe to be a function call, but got ${rhs.type} instead.`);
40
98
  }
41
99
  const firstArgument = processedArguments[0];
100
+ // If requested, return the lhs value (tee/TPipe semantics): add a Returns edge to the lhs entry
101
+ if (firstArgument && returnLhs) {
102
+ information.graph.addEdge(rootId, firstArgument.entryPoint, edge_1.EdgeType.Returns);
103
+ }
104
+ else {
105
+ const secondArgument = processedArguments[1];
106
+ if (secondArgument && !returnLhs) {
107
+ information.graph.addEdge(rootId, secondArgument.entryPoint, edge_1.EdgeType.Returns);
108
+ }
109
+ }
42
110
  const uniqueIn = information.in.slice();
43
111
  for (const ing of (firstArgument?.in ?? [])) {
44
112
  if (!uniqueIn.some(e => e.nodeId === ing.nodeId)) {