@eagleoutice/flowr 2.9.9 → 2.9.11

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 (198) hide show
  1. package/README.md +57 -54
  2. package/abstract-interpretation/absint-visitor.d.ts +16 -14
  3. package/abstract-interpretation/absint-visitor.js +93 -47
  4. package/abstract-interpretation/data-frame/mappers/arguments.d.ts +1 -1
  5. package/abstract-interpretation/data-frame/mappers/arguments.js +2 -2
  6. package/abstract-interpretation/data-frame/shape-inference.d.ts +2 -5
  7. package/abstract-interpretation/data-frame/shape-inference.js +4 -5
  8. package/abstract-interpretation/domains/abstract-domain.d.ts +4 -4
  9. package/abstract-interpretation/domains/abstract-domain.js +8 -8
  10. package/abstract-interpretation/domains/mapped-abstract-domain.d.ts +12 -5
  11. package/abstract-interpretation/domains/mapped-abstract-domain.js +47 -23
  12. package/abstract-interpretation/domains/set-range-domain.js +1 -1
  13. package/abstract-interpretation/domains/state-abstract-domain.d.ts +30 -1
  14. package/abstract-interpretation/domains/state-abstract-domain.js +130 -4
  15. package/abstract-interpretation/normalized-ast-fold.d.ts +2 -2
  16. package/abstract-interpretation/normalized-ast-fold.js +4 -3
  17. package/benchmark/slicer.js +5 -5
  18. package/benchmark/summarizer/first-phase/process.js +4 -4
  19. package/cli/repl/commands/repl-normalize.js +2 -2
  20. package/cli/repl/core.js +2 -2
  21. package/config.js +1 -1
  22. package/control-flow/cfg-simplification.d.ts +1 -0
  23. package/control-flow/cfg-simplification.js +1 -0
  24. package/control-flow/control-flow-graph.d.ts +1 -1
  25. package/control-flow/control-flow-graph.js +1 -2
  26. package/control-flow/extract-cfg.js +34 -15
  27. package/control-flow/semantic-cfg-guided-visitor.js +1 -0
  28. package/dataflow/cluster.js +1 -1
  29. package/dataflow/environments/built-in.d.ts +6 -15
  30. package/dataflow/environments/built-in.js +25 -33
  31. package/dataflow/environments/default-builtin-config.d.ts +4 -8
  32. package/dataflow/environments/default-builtin-config.js +8 -5
  33. package/dataflow/environments/reference-to-maybe.d.ts +8 -0
  34. package/dataflow/environments/reference-to-maybe.js +46 -3
  35. package/dataflow/eval/resolve/alias-tracking.d.ts +2 -2
  36. package/dataflow/eval/resolve/alias-tracking.js +6 -6
  37. package/dataflow/eval/resolve/resolve.js +12 -10
  38. package/dataflow/fn/exceptions-of-function.d.ts +1 -1
  39. package/dataflow/fn/exceptions-of-function.js +2 -1
  40. package/dataflow/graph/call-graph.d.ts +1 -1
  41. package/dataflow/graph/call-graph.js +4 -3
  42. package/dataflow/graph/dataflowgraph-builder.d.ts +1 -1
  43. package/dataflow/graph/dataflowgraph-builder.js +21 -21
  44. package/dataflow/graph/graph.d.ts +5 -5
  45. package/dataflow/graph/graph.js +36 -32
  46. package/dataflow/graph/unknown-side-effect.js +3 -1
  47. package/dataflow/info.d.ts +4 -0
  48. package/dataflow/info.js +2 -2
  49. package/dataflow/internal/linker.d.ts +4 -4
  50. package/dataflow/internal/linker.js +59 -33
  51. package/dataflow/internal/process/functions/call/argument/make-argument.d.ts +2 -1
  52. package/dataflow/internal/process/functions/call/argument/make-argument.js +3 -1
  53. package/dataflow/internal/process/functions/call/built-in/built-in-access.d.ts +1 -1
  54. package/dataflow/internal/process/functions/call/built-in/built-in-access.js +2 -1
  55. package/dataflow/internal/process/functions/call/built-in/built-in-apply.js +3 -5
  56. package/dataflow/internal/process/functions/call/built-in/built-in-expression-list.d.ts +1 -1
  57. package/dataflow/internal/process/functions/call/built-in/built-in-expression-list.js +6 -5
  58. package/dataflow/internal/process/functions/call/built-in/built-in-for-loop.js +15 -6
  59. package/dataflow/internal/process/functions/call/built-in/built-in-function-definition.d.ts +1 -1
  60. package/dataflow/internal/process/functions/call/built-in/built-in-function-definition.js +3 -2
  61. package/dataflow/internal/process/functions/call/built-in/built-in-if-then-else.js +4 -4
  62. package/dataflow/internal/process/functions/call/built-in/built-in-local.js +3 -3
  63. package/dataflow/internal/process/functions/call/built-in/built-in-repeat-loop.js +2 -2
  64. package/dataflow/internal/process/functions/call/built-in/built-in-replacement.d.ts +1 -1
  65. package/dataflow/internal/process/functions/call/built-in/built-in-replacement.js +2 -1
  66. package/dataflow/internal/process/functions/call/built-in/built-in-s-seven-new-generic.js +7 -7
  67. package/dataflow/internal/process/functions/call/built-in/built-in-s-three-dispatch.js +3 -3
  68. package/dataflow/internal/process/functions/call/built-in/built-in-source.js +22 -11
  69. package/dataflow/internal/process/functions/call/built-in/built-in-while-loop.js +22 -19
  70. package/dataflow/internal/process/functions/call/common.d.ts +1 -1
  71. package/dataflow/internal/process/functions/call/common.js +43 -35
  72. package/dataflow/internal/process/functions/call/known-call-handling.js +0 -2
  73. package/dataflow/internal/process/functions/process-argument.d.ts +1 -1
  74. package/dataflow/internal/process/functions/process-argument.js +3 -3
  75. package/dataflow/internal/process/functions/process-parameter.js +2 -2
  76. package/dataflow/origin/dfg-get-origin.d.ts +1 -1
  77. package/dataflow/origin/dfg-get-origin.js +2 -2
  78. package/documentation/doc-util/doc-types.js +1 -1
  79. package/documentation/wiki-absint.js +7 -8
  80. package/documentation/wiki-cfg.js +3 -3
  81. package/documentation/wiki-mk/doc-context.d.ts +8 -0
  82. package/documentation/wiki-mk/doc-context.js +4 -0
  83. package/documentation/wiki-normalized-ast.d.ts +1 -1
  84. package/documentation/wiki-normalized-ast.js +9 -6
  85. package/linter/linter-format.d.ts +10 -0
  86. package/linter/linter-format.js +15 -0
  87. package/linter/rules/absolute-path.js +3 -3
  88. package/linter/rules/dead-code.js +1 -1
  89. package/linter/rules/file-path-validity.js +1 -1
  90. package/linter/rules/seeded-randomness.js +1 -1
  91. package/linter/rules/unused-definition.js +1 -1
  92. package/package.json +7 -7
  93. package/project/plugins/file-plugins/files/flowr-description-file.d.ts +9 -0
  94. package/project/plugins/file-plugins/files/flowr-description-file.js +12 -0
  95. package/queries/catalog/call-context-query/call-context-query-executor.js +1 -1
  96. package/queries/catalog/call-context-query/identify-link-to-last-call-relation.d.ts +1 -1
  97. package/queries/catalog/call-context-query/identify-link-to-last-call-relation.js +4 -5
  98. package/queries/catalog/dependencies-query/dependencies-query-executor.js +2 -1
  99. package/queries/catalog/dependencies-query/dependencies-query-format.js +6 -5
  100. package/queries/catalog/df-shape-query/df-shape-query-format.d.ts +1 -1
  101. package/queries/catalog/df-shape-query/df-shape-query-format.js +3 -3
  102. package/queries/catalog/does-call-query/does-call-query-executor.js +3 -3
  103. package/queries/catalog/inspect-exceptions-query/inspect-exception-query-format.d.ts +1 -1
  104. package/queries/catalog/inspect-exceptions-query/inspect-exception-query-format.js +2 -2
  105. package/queries/catalog/inspect-higher-order-query/inspect-higher-order-query-format.d.ts +1 -1
  106. package/queries/catalog/inspect-higher-order-query/inspect-higher-order-query-format.js +1 -1
  107. package/queries/catalog/inspect-recursion-query/inspect-recursion-query-format.d.ts +1 -1
  108. package/queries/catalog/inspect-recursion-query/inspect-recursion-query-format.js +1 -1
  109. package/queries/query-print.d.ts +1 -1
  110. package/queries/query-print.js +4 -3
  111. package/r-bridge/lang-4.x/ast/model/model.d.ts +151 -4
  112. package/r-bridge/lang-4.x/ast/model/model.js +249 -0
  113. package/r-bridge/lang-4.x/ast/model/nodes/info/r-delimiter.d.ts +11 -1
  114. package/r-bridge/lang-4.x/ast/model/nodes/info/r-delimiter.js +13 -0
  115. package/r-bridge/lang-4.x/ast/model/nodes/r-access.d.ts +19 -1
  116. package/r-bridge/lang-4.x/ast/model/nodes/r-access.js +26 -0
  117. package/r-bridge/lang-4.x/ast/model/nodes/r-argument.d.ts +36 -3
  118. package/r-bridge/lang-4.x/ast/model/nodes/r-argument.js +48 -13
  119. package/r-bridge/lang-4.x/ast/model/nodes/r-binary-op.d.ts +16 -1
  120. package/r-bridge/lang-4.x/ast/model/nodes/r-binary-op.js +21 -0
  121. package/r-bridge/lang-4.x/ast/model/nodes/r-break.d.ts +11 -1
  122. package/r-bridge/lang-4.x/ast/model/nodes/r-break.js +14 -0
  123. package/r-bridge/lang-4.x/ast/model/nodes/r-comment.d.ts +8 -2
  124. package/r-bridge/lang-4.x/ast/model/nodes/r-comment.js +11 -5
  125. package/r-bridge/lang-4.x/ast/model/nodes/r-expression-list.d.ts +23 -1
  126. package/r-bridge/lang-4.x/ast/model/nodes/r-expression-list.js +32 -0
  127. package/r-bridge/lang-4.x/ast/model/nodes/r-for-loop.d.ts +11 -1
  128. package/r-bridge/lang-4.x/ast/model/nodes/r-for-loop.js +14 -0
  129. package/r-bridge/lang-4.x/ast/model/nodes/r-function-call.d.ts +19 -1
  130. package/r-bridge/lang-4.x/ast/model/nodes/r-function-call.js +26 -1
  131. package/r-bridge/lang-4.x/ast/model/nodes/r-function-definition.d.ts +11 -1
  132. package/r-bridge/lang-4.x/ast/model/nodes/r-function-definition.js +14 -0
  133. package/r-bridge/lang-4.x/ast/model/nodes/r-if-then-else.d.ts +11 -1
  134. package/r-bridge/lang-4.x/ast/model/nodes/r-if-then-else.js +14 -0
  135. package/r-bridge/lang-4.x/ast/model/nodes/r-line-directive.d.ts +12 -2
  136. package/r-bridge/lang-4.x/ast/model/nodes/r-line-directive.js +14 -0
  137. package/r-bridge/lang-4.x/ast/model/nodes/r-logical.d.ts +20 -2
  138. package/r-bridge/lang-4.x/ast/model/nodes/r-logical.js +26 -0
  139. package/r-bridge/lang-4.x/ast/model/nodes/r-next.d.ts +12 -2
  140. package/r-bridge/lang-4.x/ast/model/nodes/r-next.js +14 -0
  141. package/r-bridge/lang-4.x/ast/model/nodes/r-number.d.ts +8 -2
  142. package/r-bridge/lang-4.x/ast/model/nodes/r-number.js +11 -5
  143. package/r-bridge/lang-4.x/ast/model/nodes/r-parameter.d.ts +17 -1
  144. package/r-bridge/lang-4.x/ast/model/nodes/r-parameter.js +22 -0
  145. package/r-bridge/lang-4.x/ast/model/nodes/r-pipe.d.ts +16 -1
  146. package/r-bridge/lang-4.x/ast/model/nodes/r-pipe.js +22 -0
  147. package/r-bridge/lang-4.x/ast/model/nodes/r-project.d.ts +45 -8
  148. package/r-bridge/lang-4.x/ast/model/nodes/r-project.js +57 -16
  149. package/r-bridge/lang-4.x/ast/model/nodes/r-repeat-loop.d.ts +12 -2
  150. package/r-bridge/lang-4.x/ast/model/nodes/r-repeat-loop.js +14 -0
  151. package/r-bridge/lang-4.x/ast/model/nodes/r-string.d.ts +15 -3
  152. package/r-bridge/lang-4.x/ast/model/nodes/r-string.js +21 -6
  153. package/r-bridge/lang-4.x/ast/model/nodes/r-symbol.d.ts +21 -6
  154. package/r-bridge/lang-4.x/ast/model/nodes/r-symbol.js +22 -5
  155. package/r-bridge/lang-4.x/ast/model/nodes/r-unary-op.d.ts +16 -1
  156. package/r-bridge/lang-4.x/ast/model/nodes/r-unary-op.js +21 -0
  157. package/r-bridge/lang-4.x/ast/model/nodes/r-while-loop.d.ts +11 -1
  158. package/r-bridge/lang-4.x/ast/model/nodes/r-while-loop.js +14 -0
  159. package/r-bridge/lang-4.x/ast/model/processing/decorate.js +23 -17
  160. package/r-bridge/lang-4.x/ast/model/processing/node-id.d.ts +39 -2
  161. package/r-bridge/lang-4.x/ast/model/processing/node-id.js +52 -9
  162. package/r-bridge/lang-4.x/ast/model/processing/role.d.ts +18 -17
  163. package/r-bridge/lang-4.x/ast/model/processing/visitor.d.ts +8 -7
  164. package/r-bridge/lang-4.x/ast/model/processing/visitor.js +6 -13
  165. package/r-bridge/lang-4.x/ast/parser/json/parser.d.ts +1 -1
  166. package/r-bridge/lang-4.x/ast/parser/json/parser.js +1 -1
  167. package/r-bridge/lang-4.x/ast/parser/main/internal/expression/normalize-expression.js +4 -2
  168. package/r-bridge/lang-4.x/ast/parser/main/internal/values/normalize-number.js +1 -1
  169. package/r-bridge/lang-4.x/ast/parser/main/internal/values/normalize-string.js +2 -2
  170. package/r-bridge/lang-4.x/convert-values.d.ts +14 -5
  171. package/r-bridge/lang-4.x/convert-values.js +76 -72
  172. package/r-bridge/lang-4.x/tree-sitter/tree-sitter-normalize.js +33 -15
  173. package/r-bridge/roxygen2/roxygen-parse.js +1 -1
  174. package/r-bridge/shell-executor.js +1 -1
  175. package/reconstruct/auto-select/magic-comments.js +4 -4
  176. package/reconstruct/reconstruct.js +2 -1
  177. package/search/search-executor/search-generators.js +2 -2
  178. package/slicing/criterion/filters/all-variables.js +1 -1
  179. package/slicing/criterion/parse.d.ts +1 -1
  180. package/slicing/criterion/parse.js +5 -3
  181. package/slicing/static/slice-call.d.ts +1 -1
  182. package/slicing/static/slice-call.js +2 -2
  183. package/statistics/features/supported/assignments/assignments.js +2 -2
  184. package/statistics/features/supported/control-flow/control-flow.js +2 -2
  185. package/statistics/features/supported/data-access/data-access.js +6 -5
  186. package/statistics/features/supported/defined-functions/defined-functions.js +9 -8
  187. package/statistics/features/supported/expression-list/statistics-expression-list.js +2 -2
  188. package/statistics/features/supported/loops/loops.js +6 -5
  189. package/statistics/features/supported/used-functions/used-functions.js +2 -2
  190. package/statistics/features/supported/variables/variables.js +8 -8
  191. package/util/mermaid/ast.js +3 -3
  192. package/util/mermaid/cfg.js +3 -4
  193. package/util/mermaid/dfg.d.ts +1 -1
  194. package/util/mermaid/dfg.js +13 -12
  195. package/util/simple-df/dfg-ascii.js +1 -1
  196. package/util/version.js +1 -1
  197. package/r-bridge/lang-4.x/ast/model/collect.d.ts +0 -10
  198. package/r-bridge/lang-4.x/ast/model/collect.js +0 -25
@@ -61,7 +61,7 @@ exports.FunctionArgument = {
61
61
  },
62
62
  /**
63
63
  * Checks whether the given argument is not an empty argument.
64
- * @see {@link isEmpty}
64
+ * @see {@link FunctionArgument.isEmpty}
65
65
  */
66
66
  isNotEmpty(arg) {
67
67
  return arg !== r_function_call_1.EmptyArgument;
@@ -267,25 +267,24 @@ class DataflowGraph {
267
267
  * @see DataflowGraphVertexArgument
268
268
  */
269
269
  addVertex(vertex, fallbackEnv, asRoot = true, overwrite = false) {
270
- const oldVertex = this.vertexInformation.get(vertex.id);
270
+ const vid = vertex.id;
271
+ const oldVertex = this.vertexInformation.get(vid);
271
272
  if (oldVertex !== undefined && !overwrite) {
272
273
  return this;
273
274
  }
274
- const fallback = vertex.tag === vertex_1.VertexType.FunctionDefinition || (vertex.tag === vertex_1.VertexType.FunctionCall && !vertex.onlyBuiltin) ? fallbackEnv : undefined;
275
- this.vertexInformation.set(vertex.id, {
276
- ...vertex,
277
- // keep a clone of the original environment
278
- environment: vertex.environment ? (0, clone_1.cloneEnvironmentInformation)(vertex.environment) : fallback
279
- });
275
+ const vtag = vertex.tag;
276
+ // keep a clone of the original environment
277
+ vertex.environment = vertex.environment ? (0, clone_1.cloneEnvironmentInformation)(vertex.environment) : (vtag === vertex_1.VertexType.FunctionDefinition || (vtag === vertex_1.VertexType.FunctionCall && !vertex.onlyBuiltin) ? fallbackEnv : undefined);
278
+ this.vertexInformation.set(vid, vertex);
280
279
  const has = this.types.get(vertex.tag);
281
280
  if (has) {
282
- has.push(vertex.id);
281
+ has.push(vid);
283
282
  }
284
283
  else {
285
- this.types.set(vertex.tag, [vertex.id]);
284
+ this.types.set(vertex.tag, [vid]);
286
285
  }
287
286
  if (asRoot) {
288
- this.rootVertices.add(vertex.id);
287
+ this.rootVertices.add(vid);
289
288
  }
290
289
  return this;
291
290
  }
@@ -293,11 +292,10 @@ class DataflowGraph {
293
292
  if (fromId === toId) {
294
293
  return this;
295
294
  }
296
- /* we now that we pass all required arguments */
297
- const edge = { types: type };
298
295
  const existingFrom = this.edgeInformation.get(fromId);
299
296
  const edgeInFrom = existingFrom?.get(toId);
300
297
  if (edgeInFrom === undefined) {
298
+ const edge = { types: type };
301
299
  if (existingFrom === undefined) {
302
300
  this.edgeInformation.set(fromId, new Map([[toId, edge]]));
303
301
  }
@@ -374,8 +372,9 @@ class DataflowGraph {
374
372
  vertex.cds = reference.cds;
375
373
  }
376
374
  else {
377
- this.vertexInformation.set(reference.nodeId, { ...vertex, tag: vertex_1.VertexType.VariableDefinition });
378
- this.types.set(vertex.tag, (this.types.get(vertex.tag) ?? []).filter(id => id !== reference.nodeId));
375
+ const oldTag = vertex.tag;
376
+ vertex.tag = vertex_1.VertexType.VariableDefinition;
377
+ this.types.set(oldTag, (this.types.get(oldTag) ?? []).filter(id => id !== reference.nodeId));
379
378
  this.types.set(vertex_1.VertexType.VariableDefinition, (this.types.get(vertex_1.VertexType.VariableDefinition) ?? []).concat([reference.nodeId]));
380
379
  }
381
380
  }
@@ -384,43 +383,48 @@ class DataflowGraph {
384
383
  * @param info - The information about the new function call node
385
384
  */
386
385
  updateToFunctionCall(info) {
387
- const vertex = this.getVertex(info.id);
386
+ const infoId = info.id;
387
+ const vertex = this.getVertex(infoId);
388
388
  (0, assert_1.guard)(vertex !== undefined && (vertex.tag === vertex_1.VertexType.Use || vertex.tag === vertex_1.VertexType.Value), () => `node must be a use or value node for ${JSON.stringify(info.id)} to update it to a function call but is ${vertex?.tag}`);
389
389
  const previousTag = vertex.tag;
390
- this.vertexInformation.set(info.id, { ...vertex, ...info, tag: vertex_1.VertexType.FunctionCall });
391
- this.types.set(previousTag, (this.types.get(previousTag) ?? []).filter(id => id !== info.id));
392
- this.types.set(vertex_1.VertexType.FunctionCall, (this.types.get(vertex_1.VertexType.FunctionCall) ?? []).concat([info.id]));
390
+ this.vertexInformation.set(infoId, { ...vertex, ...info, tag: vertex_1.VertexType.FunctionCall });
391
+ this.types.set(previousTag, (this.types.get(previousTag) ?? []).filter(id => id !== infoId));
392
+ const g = this.types.get(vertex_1.VertexType.FunctionCall);
393
+ if (g) {
394
+ g.push(infoId);
395
+ }
396
+ else {
397
+ this.types.set(vertex_1.VertexType.FunctionCall, [infoId]);
398
+ }
393
399
  }
394
400
  /** If you do not pass the `to` node, this will just mark the node as maybe */
395
401
  addControlDependency(from, to, when) {
396
- to = to ? (0, node_id_1.normalizeIdToNumberIfPossible)(to) : undefined;
402
+ to = node_id_1.NodeId.normalize(to);
397
403
  const vertex = this.getVertex(from);
398
404
  (0, assert_1.guard)(vertex !== undefined, () => `node must be defined for ${from} to add control dependency`);
399
405
  vertex.cds ??= [];
400
- if (to) {
401
- let hasControlDependency = false;
402
- for (const { id, when: cond } of vertex.cds) {
403
- if (id === to && when !== cond) {
404
- hasControlDependency = true;
405
- break;
406
- }
407
- }
408
- if (!hasControlDependency) {
409
- vertex.cds.push({ id: to, when });
406
+ let hasControlDependency = false;
407
+ for (const { id, when: cond } of vertex.cds) {
408
+ if (id === to && when !== cond) {
409
+ hasControlDependency = true;
410
+ break;
410
411
  }
411
412
  }
413
+ if (!hasControlDependency) {
414
+ vertex.cds.push({ id: to, when });
415
+ }
412
416
  return this;
413
417
  }
414
418
  /** Marks the given node as having unknown side effects */
415
419
  markIdForUnknownSideEffects(id, target) {
416
420
  if (target) {
417
421
  this._unknownSideEffects.add({
418
- id: (0, node_id_1.normalizeIdToNumberIfPossible)(id),
422
+ id: node_id_1.NodeId.normalize(id),
419
423
  linkTo: typeof target.callName === 'string' ? { ...target, callName: new RegExp(target.callName) } : target
420
424
  });
421
425
  return this;
422
426
  }
423
- this._unknownSideEffects.add((0, node_id_1.normalizeIdToNumberIfPossible)(id));
427
+ this._unknownSideEffects.add(node_id_1.NodeId.normalize(id));
424
428
  return this;
425
429
  }
426
430
  /**
@@ -16,6 +16,8 @@ function onUnknownSideEffect(handler) {
16
16
  */
17
17
  function handleUnknownSideEffect(graph, env, id, target) {
18
18
  graph.markIdForUnknownSideEffects(id, target);
19
- handlers.forEach(handler => handler(graph, env, id, target));
19
+ for (const handler of handlers) {
20
+ handler(graph, env, id, target);
21
+ }
20
22
  }
21
23
  //# sourceMappingURL=unknown-side-effect.js.map
@@ -19,6 +19,10 @@ export interface ControlDependency {
19
19
  readonly when?: boolean;
20
20
  /** whether this control dependency was created due to iteration (e.g., a loop) */
21
21
  readonly byIteration?: boolean;
22
+ /**
23
+ * any file-exist assumptions made
24
+ */
25
+ readonly file?: string;
22
26
  }
23
27
  /**
24
28
  * Negates the given control dependency (i.e., flips the `when` flag).
package/dataflow/info.js CHANGED
@@ -66,7 +66,7 @@ function initializeCleanDataflowInformation(entryPoint, data) {
66
66
  in: [],
67
67
  out: [],
68
68
  environment: data.environment,
69
- graph: new graph_1.DataflowGraph(data.completeAst.idMap),
69
+ graph: new graph_1.DataflowGraph(undefined),
70
70
  entryPoint,
71
71
  exitPoints: [{ nodeId: entryPoint, type: 0 /* ExitPointType.Default */ }],
72
72
  hooks: []
@@ -138,7 +138,7 @@ function diffControlDependency(a, b, info) {
138
138
  info.report.addComment(`${info.position}Different control dependency ids. ${info.leftname}: ${JSON.stringify(a.id)} vs. ${info.rightname}: ${JSON.stringify(b.id)}`);
139
139
  }
140
140
  if (a.when !== b.when) {
141
- info.report.addComment(`${info.position}Different control dependency when. ${info.leftname}: ${a.when} vs. ${info.rightname}: ${b.when}`);
141
+ info.report.addComment(`${info.position}Different control dependency when (id: ${JSON.stringify(a.id)}). ${info.leftname}: ${a.when} vs. ${info.rightname}: ${b.when}`);
142
142
  }
143
143
  }
144
144
  /**
@@ -1,18 +1,18 @@
1
1
  import { DefaultMap } from '../../util/collections/defaultmap';
2
- import { type NodeId } from '../../r-bridge/lang-4.x/ast/model/processing/node-id';
2
+ import type { BuiltIn } from '../../r-bridge/lang-4.x/ast/model/processing/node-id';
3
+ import { NodeId } from '../../r-bridge/lang-4.x/ast/model/processing/node-id';
3
4
  import { Identifier, type IdentifierReference } from '../environments/identifier';
4
5
  import { type DataflowGraph, FunctionArgument } from '../graph/graph';
5
6
  import type { RParameter } from '../../r-bridge/lang-4.x/ast/model/nodes/r-parameter';
6
7
  import type { AstIdMap, ParentInformation } from '../../r-bridge/lang-4.x/ast/model/processing/decorate';
7
8
  import { type DataflowGraphVertexFunctionCall, type DataflowGraphVertexFunctionDefinition, type DataflowGraphVertexInfo } from '../graph/vertex';
8
- import { type BuiltIn } from '../environments/built-in';
9
9
  import type { REnvironmentInformation } from '../environments/environment';
10
10
  import type { ExitPoint } from '../info';
11
11
  export type NameIdMap = DefaultMap<Identifier, IdentifierReference[]>;
12
12
  /**
13
13
  * Find all reads within the graph that do not reference a local definition in the graph.
14
14
  */
15
- export declare function findNonLocalReads(graph: DataflowGraph, ignore: readonly IdentifierReference[]): IdentifierReference[];
15
+ export declare function findNonLocalReads(graph: DataflowGraph, ignores?: ReadonlySet<NodeId>): IdentifierReference[];
16
16
  /**
17
17
  * Produces a map from names to all identifier references sharing that name.
18
18
  */
@@ -101,4 +101,4 @@ export declare function linkCircularRedefinitionsWithinALoop(graph: DataflowGrap
101
101
  /**
102
102
  * Reapplies the loop exit points' control dependencies to the given identifier references.
103
103
  */
104
- export declare function reapplyLoopExitPoints(exits: readonly ExitPoint[], references: readonly IdentifierReference[]): void;
104
+ export declare function reapplyLoopExitPoints(exits: readonly ExitPoint[], references: readonly IdentifierReference[], graph: DataflowGraph): void;
@@ -32,27 +32,29 @@ const unnamed_call_handling_1 = require("./process/functions/call/unnamed-call-h
32
32
  /**
33
33
  * Find all reads within the graph that do not reference a local definition in the graph.
34
34
  */
35
- function findNonLocalReads(graph, ignore) {
36
- const ignores = new Set(ignore.map(i => i.nodeId));
37
- const ids = new Set(graph.vertexIdsOfType(vertex_1.VertexType.Use).concat(graph.vertexIdsOfType(vertex_1.VertexType.FunctionCall)));
35
+ function findNonLocalReads(graph, ignores = new Set()) {
36
+ const defs = new Set(graph.vertexIdsOfType(vertex_1.VertexType.VariableDefinition).concat(graph.vertexIdsOfType(vertex_1.VertexType.FunctionDefinition)));
38
37
  /* find all variable use ids which do not link to a given id */
39
38
  const nonLocalReads = [];
40
- for (const nodeId of ids) {
41
- if (ignores.has(nodeId)) {
42
- continue;
43
- }
44
- const outgoing = graph.outgoingEdges(nodeId);
45
- const name = (0, node_id_1.recoverName)(nodeId, graph.idMap);
46
- const origin = graph.getVertex(nodeId);
47
- const type = origin?.tag === vertex_1.VertexType.FunctionCall ? identifier_1.ReferenceType.Function : identifier_1.ReferenceType.Variable;
48
- if (outgoing === undefined) {
49
- nonLocalReads.push({ name, nodeId, type });
50
- continue;
51
- }
52
- for (const [target, e] of outgoing) {
53
- if (edge_1.DfEdge.includesType(e, edge_1.EdgeType.Reads) && !ids.has(target)) {
54
- nonLocalReads.push({ name, nodeId, type });
55
- break;
39
+ for (const ids of [graph.vertexIdsOfType(vertex_1.VertexType.Use), graph.vertexIdsOfType(vertex_1.VertexType.FunctionCall)]) {
40
+ for (const nodeId of ids) {
41
+ if (ignores.has(nodeId)) {
42
+ continue;
43
+ }
44
+ const outgoing = graph.outgoingEdges(nodeId);
45
+ const origin = graph.getVertex(nodeId);
46
+ const name = (0, node_id_1.recoverName)(nodeId, graph.idMap);
47
+ const type = origin?.tag === vertex_1.VertexType.FunctionCall ? identifier_1.ReferenceType.Function : identifier_1.ReferenceType.Variable;
48
+ const identifierRef = { nodeId, name, type };
49
+ if (outgoing === undefined) {
50
+ nonLocalReads.push(identifierRef);
51
+ continue;
52
+ }
53
+ for (const [target, e] of outgoing) {
54
+ if (edge_1.DfEdge.includesType(e, edge_1.EdgeType.Reads) && !defs.has(target)) {
55
+ nonLocalReads.push(identifierRef);
56
+ break;
57
+ }
56
58
  }
57
59
  }
58
60
  }
@@ -64,8 +66,9 @@ function findNonLocalReads(graph, ignore) {
64
66
  function produceNameSharedIdMap(references) {
65
67
  const nameIdShares = new defaultmap_1.DefaultMap(() => []);
66
68
  for (const reference of references) {
67
- if (reference.name) {
68
- nameIdShares.get(reference.name).push(reference);
69
+ const rn = reference.name;
70
+ if (rn) {
71
+ nameIdShares.get(rn).push(reference);
69
72
  }
70
73
  }
71
74
  return nameIdShares;
@@ -232,7 +235,7 @@ function linkFunctionCallWithSingleTarget(graph, { subflow: fnSubflow, exitPoint
232
235
  continue;
233
236
  }
234
237
  for (const { nodeId, type, value } of defs) {
235
- if (!(0, built_in_1.isBuiltIn)(nodeId)) {
238
+ if (!node_id_1.NodeId.isBuiltIn(nodeId)) {
236
239
  graph.addEdge(ingoing.nodeId, nodeId, edge_1.EdgeType.DefinedByOnCall);
237
240
  graph.addEdge(id, nodeId, edge_1.EdgeType.DefinesOnCall);
238
241
  if (type === identifier_1.ReferenceType.Function && ingoing.type === identifier_1.ReferenceType.S7MethodPrefix && Array.isArray(value)) {
@@ -288,7 +291,7 @@ function linkFunctionCall(graph, id, info, idMap, thisGraph, calledFunctionDefin
288
291
  }
289
292
  const functionDefinitionReadIds = new Set();
290
293
  for (const [t, e] of edges.entries()) {
291
- if (!(0, built_in_1.isBuiltIn)(t) && edge_1.DfEdge.doesNotIncludeType(e, edge_1.EdgeType.Argument) && edge_1.DfEdge.includesType(e, FCallLinkReadBits)) {
294
+ if (!node_id_1.NodeId.isBuiltIn(t) && edge_1.DfEdge.doesNotIncludeType(e, edge_1.EdgeType.Argument) && edge_1.DfEdge.includesType(e, FCallLinkReadBits)) {
292
295
  functionDefinitionReadIds.add(t);
293
296
  }
294
297
  }
@@ -388,7 +391,7 @@ function getAllLinkedFunctionDefinitions(functionDefinitionReadIds, dataflowGrap
388
391
  while (potential.length !== 0) {
389
392
  const cid = potential.pop();
390
393
  visited.add(cid);
391
- if ((0, built_in_1.isBuiltIn)(cid)) {
394
+ if (node_id_1.NodeId.isBuiltIn(cid)) {
392
395
  builtIns.add(cid);
393
396
  continue;
394
397
  }
@@ -435,7 +438,6 @@ function linkInputs(referencesToLinkAgainstEnvironment, environmentInformation,
435
438
  for (const bodyInput of referencesToLinkAgainstEnvironment) {
436
439
  const probableTarget = bodyInput.name ? (0, resolve_by_name_1.resolveByName)(bodyInput.name, environmentInformation, bodyInput.type) : undefined;
437
440
  if (probableTarget === undefined) {
438
- log_1.log.trace(`found no target for ${bodyInput.name ? identifier_1.Identifier.toString(bodyInput.name) : '<no-name>'}`);
439
441
  if (maybeForRemaining) {
440
442
  bodyInput.cds ??= [];
441
443
  }
@@ -473,8 +475,9 @@ function linkCircularRedefinitionsWithinALoop(graph, openIns, outgoing) {
473
475
  // this implicitly assumes that the outgoing references are ordered
474
476
  const lastOutgoing = new Map();
475
477
  for (const out of outgoing) {
476
- if (out.name) {
477
- lastOutgoing.set(out.name, out);
478
+ const on = out.name;
479
+ if (on) {
480
+ lastOutgoing.set(on, out);
478
481
  }
479
482
  }
480
483
  for (const [name, targets] of openIns.entries()) {
@@ -490,19 +493,42 @@ function linkCircularRedefinitionsWithinALoop(graph, openIns, outgoing) {
490
493
  /**
491
494
  * Reapplies the loop exit points' control dependencies to the given identifier references.
492
495
  */
493
- function reapplyLoopExitPoints(exits, references) {
496
+ function reapplyLoopExitPoints(exits, references, graph) {
494
497
  // just apply the cds of all exit points not already present
495
- const exitCds = new Set(exits.flatMap(e => e.cds).filter(assert_1.isNotUndefined));
498
+ const exitCds = exits.flatMap(e => e.cds?.map(info_1.negateControlDependency))
499
+ .filter(assert_1.isNotUndefined)
500
+ .map(cd => ({ ...cd, byIteration: true }));
501
+ const seenRefs = new Set();
496
502
  for (const ref of references) {
503
+ if (seenRefs.has(ref.nodeId)) {
504
+ continue;
505
+ }
506
+ seenRefs.add(ref.nodeId);
497
507
  for (const cd of exitCds) {
498
- const { id: cId, when: cWhen } = cd;
508
+ const { id: cId } = cd;
509
+ let setVertex = false;
499
510
  if (ref.cds) {
500
- if (!ref.cds?.find(c => c.id === cId && c.when === cWhen)) {
501
- ref.cds.push({ ...cd, byIteration: true });
511
+ if (!ref.cds?.find(c => c.id === cId)) {
512
+ ref.cds.push(cd);
513
+ setVertex = true;
502
514
  }
503
515
  }
504
516
  else {
505
- ref.cds = [{ ...cd, byIteration: true }];
517
+ ref.cds = [cd];
518
+ setVertex = true;
519
+ }
520
+ if (setVertex) {
521
+ const vertex = graph.getVertex(ref.nodeId);
522
+ if (vertex) {
523
+ if (vertex.cds) {
524
+ if (!vertex.cds?.find(c => c.id === cId)) {
525
+ vertex.cds.push(cd);
526
+ }
527
+ }
528
+ else {
529
+ vertex.cds = [cd];
530
+ }
531
+ }
506
532
  }
507
533
  }
508
534
  }
@@ -2,6 +2,7 @@ import type { RNode } from '../../../../../../r-bridge/lang-4.x/ast/model/model'
2
2
  import type { AstIdMap, ParentInformation } from '../../../../../../r-bridge/lang-4.x/ast/model/processing/decorate';
3
3
  import { EmptyArgument } from '../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-function-call';
4
4
  import type { RUnnamedArgument } from '../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-argument';
5
+ import { RArgument } from '../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-argument';
5
6
  /**
6
7
  * Converts a normalized node into an unnamed argument (wraps it with an argument node).
7
8
  */
@@ -9,4 +10,4 @@ export declare function toUnnamedArgument<OtherInfo>(node: RNode<OtherInfo & Par
9
10
  /**
10
11
  * Wraps the given nodes as unnamed arguments where necessary.
11
12
  */
12
- export declare function wrapArgumentsUnnamed<OtherInfo>(nodes: readonly (RNode<OtherInfo & ParentInformation> | typeof EmptyArgument | undefined)[], idMap: AstIdMap<OtherInfo>): ("<>" | import("../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-argument").RArgument<OtherInfo & ParentInformation>)[];
13
+ export declare function wrapArgumentsUnnamed<OtherInfo>(nodes: readonly (RNode<OtherInfo & ParentInformation> | typeof EmptyArgument | undefined)[], idMap: AstIdMap<OtherInfo>): ("<>" | RArgument<OtherInfo & ParentInformation>)[];
@@ -4,7 +4,9 @@ exports.toUnnamedArgument = toUnnamedArgument;
4
4
  exports.wrapArgumentsUnnamed = wrapArgumentsUnnamed;
5
5
  const range_1 = require("../../../../../../util/range");
6
6
  const r_function_call_1 = require("../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-function-call");
7
+ const r_argument_1 = require("../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-argument");
7
8
  const type_1 = require("../../../../../../r-bridge/lang-4.x/ast/model/type");
9
+ const graph_1 = require("../../../../../graph/graph");
8
10
  /**
9
11
  * Converts a normalized node into an unnamed argument (wraps it with an argument node).
10
12
  */
@@ -30,6 +32,6 @@ function toUnnamedArgument(node, idMap) {
30
32
  * Wraps the given nodes as unnamed arguments where necessary.
31
33
  */
32
34
  function wrapArgumentsUnnamed(nodes, idMap) {
33
- return nodes.map(n => n === r_function_call_1.EmptyArgument || n?.type === type_1.RType.Argument ? n : toUnnamedArgument(n, idMap));
35
+ return nodes.map(n => graph_1.FunctionArgument.isEmpty(n) || r_argument_1.RArgument.is(n) ? n : toUnnamedArgument(n, idMap));
34
36
  }
35
37
  //# sourceMappingURL=make-argument.js.map
@@ -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 RFunctionArgument } from '../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-function-call';
5
5
  import type { RSymbol } from '../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-symbol';
6
- import type { NodeId } from '../../../../../../r-bridge/lang-4.x/ast/model/processing/node-id';
6
+ import { NodeId } from '../../../../../../r-bridge/lang-4.x/ast/model/processing/node-id';
7
7
  import type { ForceArguments } from '../common';
8
8
  /**
9
9
  * Processes different types of access operations.
@@ -4,6 +4,7 @@ exports.processAccess = processAccess;
4
4
  exports.symbolArgumentsToStrings = symbolArgumentsToStrings;
5
5
  const known_call_handling_1 = require("../known-call-handling");
6
6
  const r_function_call_1 = require("../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-function-call");
7
+ const node_id_1 = require("../../../../../../r-bridge/lang-4.x/ast/model/processing/node-id");
7
8
  const logger_1 = require("../../../../../logger");
8
9
  const type_1 = require("../../../../../../r-bridge/lang-4.x/ast/model/type");
9
10
  const edge_1 = require("../../../../../graph/edge");
@@ -94,7 +95,7 @@ function processAccess(name, args, rootId, data, config) {
94
95
  function processNumberBasedAccess(data, name, args, rootId, config, head) {
95
96
  const existing = data.environment.current.memory.get(':=');
96
97
  const outInfo = { definitionRootNodes: [] };
97
- const tableAssignId = (0, built_in_1.builtInId)(':=-table');
98
+ const tableAssignId = node_id_1.NodeId.toBuiltIn(':=-table');
98
99
  data.environment.current.memory.set(':=', [{
99
100
  type: identifier_1.ReferenceType.BuiltInFunction,
100
101
  definedAt: tableAssignId,
@@ -15,6 +15,7 @@ const r_value_1 = require("../../../../../eval/values/r-value");
15
15
  const log_1 = require("../../../../../../util/log");
16
16
  const alias_tracking_1 = require("../../../../../eval/resolve/alias-tracking");
17
17
  const built_in_1 = require("../../../../../environments/built-in");
18
+ const r_string_1 = require("../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-string");
18
19
  /**
19
20
  * Process an apply call like `vapply` or `mapply`.
20
21
  */
@@ -65,13 +66,10 @@ function processApply(name, args, rootId, data, config) {
65
66
  let functionName = undefined;
66
67
  let anonymous = false;
67
68
  const val = arg.value;
68
- if (unquoteFunction && val.type === type_1.RType.String) {
69
+ if (unquoteFunction && r_string_1.RString.is(val)) {
69
70
  functionId = val.info.id;
70
71
  functionName = val.content.str;
71
- information = {
72
- ...information,
73
- in: [...information.in, { type: identifier_1.ReferenceType.Function, name: functionName, cds: data.cds, nodeId: functionId }]
74
- };
72
+ information.in = [...information.in, { type: identifier_1.ReferenceType.Function, name: functionName, cds: data.cds, nodeId: functionId }];
75
73
  }
76
74
  else if (val.type === type_1.RType.Symbol) {
77
75
  functionId = val.info.id;
@@ -4,7 +4,7 @@
4
4
  */
5
5
  import type { DataflowInformation } from '../../../../../info';
6
6
  import { type DataflowProcessorInformation } from '../../../../../processor';
7
- import type { NodeId } from '../../../../../../r-bridge/lang-4.x/ast/model/processing/node-id';
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
9
  import type { RFunctionArgument } 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';
@@ -7,6 +7,7 @@ const linker_1 = require("../../../../linker");
7
7
  const assert_1 = require("../../../../../../util/assert");
8
8
  const unpack_argument_1 = require("../argument/unpack-argument");
9
9
  const common_1 = require("../common");
10
+ const node_id_1 = require("../../../../../../r-bridge/lang-4.x/ast/model/processing/node-id");
10
11
  const graph_1 = require("../../../../../graph/graph");
11
12
  const identifier_1 = require("../../../../../environments/identifier");
12
13
  const resolve_by_name_1 = require("../../../../../environments/resolve-by-name");
@@ -20,13 +21,13 @@ const log_1 = require("../../../../../../util/log");
20
21
  const reference_to_maybe_1 = require("../../../../../environments/reference-to-maybe");
21
22
  function linkReadNameToWriteIfPossible(read, environments, listEnvironments, remainingRead, nextGraph) {
22
23
  const readName = read.name && identifier_1.Identifier.isDotDotDotAccess(read.name) ? identifier_1.Identifier.dotdotdot() : read.name;
23
- const readId = readName ? identifier_1.Identifier.getName(readName) : undefined;
24
24
  const probableTarget = readName ? (0, resolve_by_name_1.resolveByName)(readName, environments, read.type) : undefined;
25
25
  // record if at least one has not been defined
26
26
  if (probableTarget === undefined || probableTarget.some(t => !listEnvironments.has(t.nodeId) || !(0, info_1.happensInEveryBranch)(t.cds))) {
27
+ const readId = readName ? identifier_1.Identifier.getName(readName) : undefined;
27
28
  const has = remainingRead.get(readId);
28
29
  if (has) {
29
- if (!has?.some(h => h.nodeId === read.nodeId && h.name === read.name && h.cds === read.cds)) {
30
+ if (!has.some(h => h.nodeId === read.nodeId && h.name === read.name && h.cds === read.cds)) {
30
31
  has.push(read);
31
32
  }
32
33
  }
@@ -42,7 +43,7 @@ function linkReadNameToWriteIfPossible(read, environments, listEnvironments, rem
42
43
  const rid = read.nodeId;
43
44
  for (const target of probableTarget) {
44
45
  const tid = target.nodeId;
45
- if ((read.type === identifier_1.ReferenceType.Function || read.type === identifier_1.ReferenceType.BuiltInFunction) && (0, built_in_1.isBuiltIn)(target.definedAt)) {
46
+ if (node_id_1.NodeId.isBuiltIn(target.definedAt) && (read.type === identifier_1.ReferenceType.Function || read.type === identifier_1.ReferenceType.BuiltInFunction)) {
46
47
  nextGraph.addEdge(rid, tid, edge_1.EdgeType.Reads | edge_1.EdgeType.Calls);
47
48
  }
48
49
  else {
@@ -66,7 +67,7 @@ function updateSideEffectsForCalledFunctions(calledEnvs, inputEnvironment, nextG
66
67
  while (!current?.builtInEnv) {
67
68
  for (const definitions of current.memory.values()) {
68
69
  for (const def of definitions) {
69
- if (!(0, built_in_1.isBuiltIn)(def.definedAt)) {
70
+ if (!node_id_1.NodeId.isBuiltIn(def.definedAt)) {
70
71
  hasUpdate = true;
71
72
  nextGraph.addEdge(def.nodeId, functionCall, edge_1.EdgeType.SideEffectOnCall);
72
73
  }
@@ -179,7 +180,7 @@ function processExpressionList(name, args, rootId, data) {
179
180
  argumentProcessResult: processedExpressions,
180
181
  origin: built_in_1.BuiltInProcName.ExpressionList
181
182
  });
182
- nextGraph.addEdge(rootId, (0, built_in_1.builtInId)('{'), edge_1.EdgeType.Reads | edge_1.EdgeType.Calls);
183
+ nextGraph.addEdge(rootId, node_id_1.NodeId.toBuiltIn('{'), edge_1.EdgeType.Reads | edge_1.EdgeType.Calls);
183
184
  // process all exit points as potential returns:
184
185
  for (const exit of exitPoints) {
185
186
  if (exit.type === 1 /* ExitPointType.Return */ || exit.type === 0 /* ExitPointType.Default */) {
@@ -29,6 +29,8 @@ function processForLoop(name, args, rootId, data) {
29
29
  return (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data, origin: 'default' }).information;
30
30
  }
31
31
  const [variableArg, vectorArg, bodyArg] = args.map(e => (0, unpack_argument_1.unpackNonameArg)(e));
32
+ // we store the original environment here, as we merge it back lter in case the for-loop never executes
33
+ const origEnv = data.environment;
32
34
  (0, assert_1.guard)(variableArg !== undefined && vectorArg !== undefined && bodyArg !== undefined, () => `For-Loop ${JSON.stringify(args)} has missing arguments! Bad!`);
33
35
  const vector = (0, processor_1.processDataflowFor)(vectorArg, data);
34
36
  if ((0, info_1.alwaysExits)(vector)) {
@@ -41,23 +43,29 @@ function processForLoop(name, args, rootId, data) {
41
43
  let headEnvironments = (0, overwrite_1.overwriteEnvironment)(vector.environment, variable.environment);
42
44
  const headGraph = variable.graph.mergeWith(vector.graph);
43
45
  const writtenVariable = variable.unknownReferences.concat(variable.in);
46
+ const writtenIds = new Set();
44
47
  for (const write of writtenVariable) {
48
+ writtenIds.add(write.nodeId);
45
49
  headEnvironments = (0, define_1.define)({ ...write, definedAt: name.info.id, type: identifier_1.ReferenceType.Variable }, false, headEnvironments);
46
50
  }
47
- data = { ...data, cds: [...data.cds ?? [], { id: name.info.id, when: true }], environment: headEnvironments };
51
+ data.environment = headEnvironments;
48
52
  const body = (0, processor_1.processDataflowFor)(bodyArg, data);
49
- const nextGraph = headGraph.mergeWith(body.graph);
50
53
  const outEnvironment = (0, append_1.appendEnvironment)(headEnvironments, body.environment);
54
+ const cd = [{ id: name.info.id, when: true }];
55
+ const bodyRefs = body.in.concat(body.unknownReferences);
56
+ (0, reference_to_maybe_1.applyCdsToAllInGraphButConstants)(body.graph, bodyRefs, cd);
57
+ const nextGraph = headGraph.mergeWith(body.graph);
51
58
  // now we have to identify all reads that may be effected by a circular redefinition
52
59
  // for this, we search for all reads with a non-local read resolve!
53
- const nameIdShares = (0, linker_1.produceNameSharedIdMap)((0, linker_1.findNonLocalReads)(nextGraph, writtenVariable));
60
+ const nameIdShares = (0, linker_1.produceNameSharedIdMap)((0, linker_1.findNonLocalReads)(nextGraph, writtenIds));
54
61
  for (const write of writtenVariable) {
55
62
  nextGraph.addEdge(write.nodeId, vector.entryPoint, edge_1.EdgeType.DefinedBy);
56
63
  nextGraph.setDefinitionOfVertex(write);
57
64
  }
58
- const outgoing = variable.out.concat(writtenVariable, (0, reference_to_maybe_1.makeAllMaybe)(body.out, nextGraph, outEnvironment, true));
65
+ (0, reference_to_maybe_1.applyCdToReferences)(body.out, cd);
66
+ const outgoing = variable.out.concat(writtenVariable, body.out);
59
67
  (0, linker_1.linkCircularRedefinitionsWithinALoop)(nextGraph, nameIdShares, body.out);
60
- (0, linker_1.reapplyLoopExitPoints)(body.exitPoints, body.in.concat(body.out, body.unknownReferences));
68
+ (0, linker_1.reapplyLoopExitPoints)(body.exitPoints, body.in.concat(body.out, body.unknownReferences), nextGraph);
61
69
  (0, common_1.patchFunctionCall)({
62
70
  nextGraph,
63
71
  rootId,
@@ -78,7 +86,8 @@ function processForLoop(name, args, rootId, data) {
78
86
  graph: nextGraph,
79
87
  entryPoint: name.info.id,
80
88
  exitPoints: (0, info_1.filterOutLoopExitPoints)(body.exitPoints),
81
- environment: outEnvironment,
89
+ // if we can not be sure that the for-loop runs once, we have to merge back the original environment, as the body may never execute
90
+ environment: (0, append_1.appendEnvironment)(origEnv, outEnvironment),
82
91
  hooks: variable.hooks.concat(vector.hooks, body.hooks),
83
92
  };
84
93
  }
@@ -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 { RSymbol } from '../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-symbol';
5
5
  import { type RFunctionArgument } from '../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-function-call';
6
- import type { NodeId } from '../../../../../../r-bridge/lang-4.x/ast/model/processing/node-id';
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';
9
9
  import type { ReadOnlyFlowrAnalyzerContext } from '../../../../../../project/context/flowr-analyzer-context';
@@ -11,6 +11,7 @@ const unpack_argument_1 = require("../argument/unpack-argument");
11
11
  const assert_1 = require("../../../../../../util/assert");
12
12
  const logger_1 = require("../../../../../logger");
13
13
  const r_function_call_1 = require("../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-function-call");
14
+ const node_id_1 = require("../../../../../../r-bridge/lang-4.x/ast/model/processing/node-id");
14
15
  const graph_1 = require("../../../../../graph/graph");
15
16
  const identifier_1 = require("../../../../../environments/identifier");
16
17
  const overwrite_1 = require("../../../../../environments/overwrite");
@@ -248,7 +249,7 @@ function updateNestedFunctionCalls(graph, outEnvironment) {
248
249
  const collectedNextMethods = new Set();
249
250
  const treatAsS3 = origin.includes(built_in_1.BuiltInProcName.S3Dispatch);
250
251
  for (const target of targets) {
251
- if ((0, built_in_1.isBuiltIn)(target)) {
252
+ if (node_id_1.NodeId.isBuiltIn(target)) {
252
253
  graph.addEdge(id, target, edge_1.EdgeType.Calls);
253
254
  continue;
254
255
  }
@@ -289,7 +290,7 @@ function updateNestedFunctionCalls(graph, outEnvironment) {
289
290
  const inId = ingoing.nodeId;
290
291
  (0, log_1.expensiveTrace)(logger_1.dataflowLogger, () => `Found ${resolved.length} references to open ref ${id} in closure of function definition ${id}`);
291
292
  for (const { nodeId } of resolved) {
292
- if (!(0, built_in_1.isBuiltIn)(nodeId)) {
293
+ if (!node_id_1.NodeId.isBuiltIn(nodeId)) {
293
294
  graph.addEdge(inId, nodeId, edge_1.EdgeType.DefinedByOnCall);
294
295
  graph.addEdge(id, nodeId, edge_1.EdgeType.DefinesOnCall);
295
296
  }
@@ -14,8 +14,8 @@ const general_1 = require("../../../../../eval/values/general");
14
14
  const alias_tracking_1 = require("../../../../../eval/resolve/alias-tracking");
15
15
  const reference_to_maybe_1 = require("../../../../../environments/reference-to-maybe");
16
16
  const linker_1 = require("../../../../linker");
17
- const r_argument_1 = require("../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-argument");
18
17
  const built_in_1 = require("../../../../../environments/built-in");
18
+ const r_argument_1 = require("../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-argument");
19
19
  function getArguments(config, args) {
20
20
  let condArg;
21
21
  let thenArg;
@@ -28,9 +28,9 @@ function getArguments(config, args) {
28
28
  '...': '...'
29
29
  };
30
30
  const argMaps = (0, linker_1.invertArgumentMap)((0, linker_1.pMatch)((0, common_1.convertFnArguments)(args), params));
31
- condArg = (0, unpack_argument_1.unpackArg)((0, r_argument_1.getArgumentWithId)(args, argMaps.get('cond')?.[0]));
32
- thenArg = (0, unpack_argument_1.unpackArg)((0, r_argument_1.getArgumentWithId)(args, argMaps.get('yes')?.[0]));
33
- otherwiseArg = (0, unpack_argument_1.unpackArg)((0, r_argument_1.getArgumentWithId)(args, argMaps.get('no')?.[0]));
31
+ condArg = (0, unpack_argument_1.unpackArg)(r_argument_1.RArgument.getWithId(args, argMaps.get('cond')?.[0]));
32
+ thenArg = (0, unpack_argument_1.unpackArg)(r_argument_1.RArgument.getWithId(args, argMaps.get('yes')?.[0]));
33
+ otherwiseArg = (0, unpack_argument_1.unpackArg)(r_argument_1.RArgument.getWithId(args, argMaps.get('no')?.[0]));
34
34
  }
35
35
  else {
36
36
  [condArg, thenArg, otherwiseArg] = args.map(e => (0, unpack_argument_1.unpackArg)(e));