@eagleoutice/flowr 2.6.3 → 2.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (161) hide show
  1. package/README.md +13 -13
  2. package/abstract-interpretation/data-frame/absint-visitor.d.ts +1 -1
  3. package/abstract-interpretation/data-frame/absint-visitor.js +3 -3
  4. package/abstract-interpretation/data-frame/dataframe-domain.d.ts +4 -7
  5. package/abstract-interpretation/data-frame/dataframe-domain.js +5 -11
  6. package/abstract-interpretation/data-frame/mappers/access-mapper.d.ts +3 -1
  7. package/abstract-interpretation/data-frame/mappers/access-mapper.js +3 -2
  8. package/abstract-interpretation/data-frame/mappers/arguments.js +2 -2
  9. package/abstract-interpretation/data-frame/mappers/assignment-mapper.d.ts +3 -1
  10. package/abstract-interpretation/data-frame/mappers/assignment-mapper.js +3 -2
  11. package/abstract-interpretation/data-frame/mappers/function-mapper.d.ts +1 -1
  12. package/abstract-interpretation/data-frame/mappers/function-mapper.js +8 -8
  13. package/abstract-interpretation/data-frame/mappers/replacement-mapper.d.ts +3 -1
  14. package/abstract-interpretation/data-frame/mappers/replacement-mapper.js +3 -2
  15. package/abstract-interpretation/data-frame/semantics.js +47 -42
  16. package/abstract-interpretation/data-frame/shape-inference.d.ts +1 -1
  17. package/abstract-interpretation/domains/abstract-domain.d.ts +1 -0
  18. package/abstract-interpretation/domains/abstract-domain.js +3 -2
  19. package/abstract-interpretation/domains/bounded-set-domain.js +1 -1
  20. package/abstract-interpretation/domains/interval-domain.d.ts +2 -2
  21. package/abstract-interpretation/domains/interval-domain.js +3 -6
  22. package/abstract-interpretation/domains/lattice.d.ts +2 -0
  23. package/abstract-interpretation/domains/lattice.js +3 -1
  24. package/abstract-interpretation/domains/positive-interval-domain.d.ts +1 -1
  25. package/abstract-interpretation/domains/positive-interval-domain.js +1 -1
  26. package/abstract-interpretation/domains/satisfiable-domain.d.ts +2 -2
  27. package/abstract-interpretation/domains/satisfiable-domain.js +2 -2
  28. package/abstract-interpretation/domains/set-range-domain.d.ts +98 -0
  29. package/abstract-interpretation/domains/set-range-domain.js +400 -0
  30. package/abstract-interpretation/domains/set-upper-bound-domain.js +2 -2
  31. package/abstract-interpretation/domains/singleton-domain.js +2 -2
  32. package/benchmark/slicer.d.ts +2 -1
  33. package/benchmark/slicer.js +37 -15
  34. package/benchmark/stats/print.js +8 -5
  35. package/benchmark/stats/stats.d.ts +3 -2
  36. package/benchmark/summarizer/data.d.ts +11 -8
  37. package/benchmark/summarizer/first-phase/process.js +11 -8
  38. package/benchmark/summarizer/second-phase/process.js +24 -18
  39. package/control-flow/cfg-dead-code.js +3 -2
  40. package/control-flow/useless-loop.js +4 -2
  41. package/core/steps/all/static-slicing/00-slice.d.ts +3 -0
  42. package/core/steps/all/static-slicing/00-slice.js +2 -1
  43. package/core/steps/pipeline/default-pipelines.d.ts +42 -42
  44. package/dataflow/cluster.js +2 -2
  45. package/dataflow/environments/append.d.ts +5 -0
  46. package/dataflow/environments/append.js +6 -20
  47. package/dataflow/environments/built-in.d.ts +2 -1
  48. package/dataflow/environments/clone.d.ts +1 -1
  49. package/dataflow/environments/clone.js +3 -27
  50. package/dataflow/environments/define.d.ts +7 -3
  51. package/dataflow/environments/define.js +9 -56
  52. package/dataflow/environments/diff.js +1 -1
  53. package/dataflow/environments/environment.d.ts +48 -28
  54. package/dataflow/environments/environment.js +187 -62
  55. package/dataflow/environments/overwrite.js +2 -45
  56. package/dataflow/environments/reference-to-maybe.d.ts +13 -0
  57. package/dataflow/environments/reference-to-maybe.js +54 -0
  58. package/dataflow/environments/resolve-by-name.d.ts +6 -1
  59. package/dataflow/environments/resolve-by-name.js +56 -4
  60. package/dataflow/environments/scoping.d.ts +2 -2
  61. package/dataflow/environments/scoping.js +7 -7
  62. package/dataflow/eval/resolve/alias-tracking.d.ts +10 -4
  63. package/dataflow/eval/resolve/alias-tracking.js +15 -13
  64. package/dataflow/eval/resolve/resolve-argument.d.ts +2 -1
  65. package/dataflow/eval/resolve/resolve-argument.js +8 -8
  66. package/dataflow/eval/resolve/resolve.d.ts +13 -11
  67. package/dataflow/eval/resolve/resolve.js +16 -15
  68. package/dataflow/extractor.js +1 -7
  69. package/dataflow/fn/higher-order-function.d.ts +2 -1
  70. package/dataflow/fn/higher-order-function.js +4 -4
  71. package/dataflow/graph/dataflowgraph-builder.d.ts +9 -5
  72. package/dataflow/graph/dataflowgraph-builder.js +21 -11
  73. package/dataflow/graph/diff-dataflow-graph.js +2 -2
  74. package/dataflow/graph/graph.d.ts +10 -2
  75. package/dataflow/graph/graph.js +41 -12
  76. package/dataflow/graph/invert-dfg.d.ts +3 -2
  77. package/dataflow/graph/invert-dfg.js +3 -3
  78. package/dataflow/graph/resolve-graph.d.ts +2 -1
  79. package/dataflow/graph/resolve-graph.js +2 -2
  80. package/dataflow/graph/vertex.d.ts +3 -3
  81. package/dataflow/graph/vertex.js +3 -3
  82. package/dataflow/info.d.ts +1 -1
  83. package/dataflow/internal/linker.js +3 -7
  84. package/dataflow/internal/process/functions/call/argument/unpack-argument.d.ts +7 -1
  85. package/dataflow/internal/process/functions/call/argument/unpack-argument.js +12 -3
  86. package/dataflow/internal/process/functions/call/built-in/built-in-access.js +3 -3
  87. package/dataflow/internal/process/functions/call/built-in/built-in-apply.js +2 -2
  88. package/dataflow/internal/process/functions/call/built-in/built-in-assignment.d.ts +3 -1
  89. package/dataflow/internal/process/functions/call/built-in/built-in-assignment.js +3 -3
  90. package/dataflow/internal/process/functions/call/built-in/built-in-eval.js +9 -9
  91. package/dataflow/internal/process/functions/call/built-in/built-in-expression-list.js +9 -7
  92. package/dataflow/internal/process/functions/call/built-in/built-in-for-loop.js +3 -3
  93. package/dataflow/internal/process/functions/call/built-in/built-in-function-definition.d.ts +2 -1
  94. package/dataflow/internal/process/functions/call/built-in/built-in-function-definition.js +9 -13
  95. package/dataflow/internal/process/functions/call/built-in/built-in-get.js +1 -1
  96. package/dataflow/internal/process/functions/call/built-in/built-in-if-then-else.d.ts +3 -1
  97. package/dataflow/internal/process/functions/call/built-in/built-in-if-then-else.js +8 -6
  98. package/dataflow/internal/process/functions/call/built-in/built-in-library.js +1 -1
  99. package/dataflow/internal/process/functions/call/built-in/built-in-pipe.js +1 -1
  100. package/dataflow/internal/process/functions/call/built-in/built-in-repeat-loop.js +1 -1
  101. package/dataflow/internal/process/functions/call/built-in/built-in-replacement.js +3 -3
  102. package/dataflow/internal/process/functions/call/built-in/built-in-rm.js +6 -4
  103. package/dataflow/internal/process/functions/call/built-in/built-in-source.js +1 -1
  104. package/dataflow/internal/process/functions/call/built-in/built-in-while-loop.js +5 -5
  105. package/dataflow/internal/process/functions/call/common.js +2 -3
  106. package/dataflow/internal/process/functions/call/known-call-handling.js +1 -1
  107. package/dataflow/internal/process/functions/call/unnamed-call-handling.js +1 -1
  108. package/dataflow/internal/process/functions/process-argument.js +1 -1
  109. package/dataflow/internal/process/process-symbol.js +1 -1
  110. package/dataflow/internal/process/process-value.d.ts +1 -1
  111. package/dataflow/internal/process/process-value.js +7 -7
  112. package/dataflow/processor.d.ts +1 -5
  113. package/documentation/doc-util/doc-dfg.js +3 -2
  114. package/documentation/doc-util/doc-normalized-ast.js +3 -2
  115. package/documentation/doc-util/doc-types.d.ts +1 -1
  116. package/documentation/doc-util/doc-types.js +2 -2
  117. package/documentation/wiki-analyzer.js +14 -1
  118. package/documentation/wiki-dataflow-graph.js +4 -5
  119. package/documentation/wiki-faq.js +0 -1
  120. package/documentation/wiki-linter.js +1 -1
  121. package/documentation/wiki-mk/doc-maker.js +2 -1
  122. package/linter/linter-rules.d.ts +2 -2
  123. package/linter/rules/absolute-path.js +4 -4
  124. package/linter/rules/dataframe-access-validation.d.ts +1 -1
  125. package/linter/rules/dataframe-access-validation.js +1 -1
  126. package/linter/rules/function-finder-util.d.ts +2 -2
  127. package/linter/rules/function-finder-util.js +1 -1
  128. package/linter/rules/network-functions.js +1 -1
  129. package/linter/rules/seeded-randomness.d.ts +1 -1
  130. package/linter/rules/seeded-randomness.js +5 -5
  131. package/package.json +1 -2
  132. package/project/context/flowr-analyzer-context.d.ts +7 -0
  133. package/project/context/flowr-analyzer-context.js +3 -0
  134. package/project/context/flowr-analyzer-environment-context.d.ts +47 -0
  135. package/project/context/flowr-analyzer-environment-context.js +50 -0
  136. package/queries/catalog/call-context-query/call-context-query-executor.js +1 -4
  137. package/queries/catalog/control-flow-query/control-flow-query-format.js +3 -2
  138. package/queries/catalog/dataflow-lens-query/dataflow-lens-query-executor.js +1 -1
  139. package/queries/catalog/dependencies-query/dependencies-query-executor.js +4 -4
  140. package/queries/catalog/df-shape-query/df-shape-query-executor.d.ts +1 -1
  141. package/queries/catalog/df-shape-query/df-shape-query-executor.js +1 -1
  142. package/queries/catalog/df-shape-query/df-shape-query-format.d.ts +4 -4
  143. package/queries/catalog/df-shape-query/df-shape-query-format.js +2 -2
  144. package/queries/catalog/inspect-higher-order-query/inspect-higher-order-query-executor.js +3 -3
  145. package/queries/catalog/resolve-value-query/resolve-value-query-executor.js +1 -1
  146. package/queries/catalog/static-slice-query/static-slice-query-executor.js +1 -1
  147. package/slicing/static/slice-call.d.ts +3 -2
  148. package/slicing/static/slice-call.js +4 -4
  149. package/slicing/static/static-slicer.d.ts +3 -1
  150. package/slicing/static/static-slicer.js +6 -7
  151. package/statistics/features/supported/control-flow/control-flow.js +1 -1
  152. package/statistics/features/supported/used-functions/used-functions.js +1 -1
  153. package/statistics/features/supported/variables/variables.js +2 -1
  154. package/util/containers.js +1 -1
  155. package/util/mermaid/dfg.d.ts +1 -0
  156. package/util/mermaid/dfg.js +3 -3
  157. package/util/simple-df/dfg-view.d.ts +2 -1
  158. package/util/simple-df/dfg-view.js +2 -2
  159. package/util/version.js +1 -1
  160. package/dataflow/environments/remove.d.ts +0 -12
  161. package/dataflow/environments/remove.js +0 -52
@@ -16,7 +16,6 @@ const identifier_1 = require("../../../../../environments/identifier");
16
16
  const overwrite_1 = require("../../../../../environments/overwrite");
17
17
  const vertex_1 = require("../../../../../graph/vertex");
18
18
  const scoping_1 = require("../../../../../environments/scoping");
19
- const environment_1 = require("../../../../../environments/environment");
20
19
  const resolve_by_name_1 = require("../../../../../environments/resolve-by-name");
21
20
  const edge_1 = require("../../../../../graph/edge");
22
21
  const log_1 = require("../../../../../../util/log");
@@ -31,7 +30,7 @@ function processFunctionDefinition(name, args, rootId, data) {
31
30
  }
32
31
  /* we remove the last argument, as it is the body */
33
32
  const parameters = args.slice(0, -1);
34
- const bodyArg = (0, unpack_argument_1.unpackArgument)(args[args.length - 1]);
33
+ const bodyArg = (0, unpack_argument_1.unpackNonameArg)(args[args.length - 1]);
35
34
  (0, assert_1.guard)(bodyArg !== undefined, () => `Function Definition ${JSON.stringify(args)} has missing body! This is bad!`);
36
35
  const originalEnvironment = data.environment;
37
36
  // within a function def we do not pass on the outer binds as they could be overwritten when called
@@ -74,7 +73,7 @@ function processFunctionDefinition(name, args, rootId, data) {
74
73
  id: read.nodeId,
75
74
  environment: undefined,
76
75
  cds: undefined
77
- });
76
+ }, data.ctx.env.makeCleanEnv());
78
77
  }
79
78
  }
80
79
  const flow = {
@@ -95,7 +94,7 @@ function processFunctionDefinition(name, args, rootId, data) {
95
94
  cds: data.controlDependencies,
96
95
  subflow: flow,
97
96
  exitPoints: exitPoints?.filter(e => e.type === 1 /* ExitPointType.Return */ || e.type === 0 /* ExitPointType.Default */).map(e => e.nodeId) ?? []
98
- });
97
+ }, data.ctx.env.makeCleanEnv());
99
98
  return {
100
99
  /* nothing escapes a function definition, but the function itself, will be forced in assignment: { nodeId: functionDefinition.info.id, scope: data.activeScope, used: 'always', name: functionDefinition.info.id as string } */
101
100
  unknownReferences: [],
@@ -112,8 +111,8 @@ function processFunctionDefinition(name, args, rootId, data) {
112
111
  /**
113
112
  *
114
113
  */
115
- function retrieveActiveEnvironment(callerEnvironment, baseEnvironment) {
116
- callerEnvironment ??= (0, environment_1.initializeCleanEnvironments)(undefined, true);
114
+ function retrieveActiveEnvironment(callerEnvironment, baseEnvironment, ctx) {
115
+ callerEnvironment ??= ctx.env.makeCleanEnv();
117
116
  let level = callerEnvironment.level ?? 0;
118
117
  if (baseEnvironment.level !== level) {
119
118
  while (baseEnvironment.level < level) {
@@ -135,10 +134,7 @@ function retrieveActiveEnvironment(callerEnvironment, baseEnvironment) {
135
134
  function updateNestedFunctionClosures(graph, outEnvironment, fnId) {
136
135
  // track *all* function definitions - including those nested within the current graph,
137
136
  // try to resolve their 'in' by only using the lowest scope which will be popped after this definition
138
- for (const [id, { subflow, tag }] of graph.vertices(true)) {
139
- if (tag !== vertex_1.VertexType.FunctionDefinition) {
140
- continue;
141
- }
137
+ for (const [id, { subflow }] of graph.verticesOfType(vertex_1.VertexType.FunctionDefinition)) {
142
138
  const ingoingRefs = subflow.in;
143
139
  const remainingIn = [];
144
140
  for (const ingoing of ingoingRefs) {
@@ -171,8 +167,8 @@ function updateNestedFunctionClosures(graph, outEnvironment, fnId) {
171
167
  function updateNestedFunctionCalls(graph, outEnvironment) {
172
168
  // track *all* function definitions - including those nested within the current graph,
173
169
  // try to resolve their 'in' by only using the lowest scope which will be popped after this definition
174
- for (const [id, { onlyBuiltin, tag, environment, name }] of graph.vertices(true)) {
175
- if (tag !== vertex_1.VertexType.FunctionCall || !name || onlyBuiltin) {
170
+ for (const [id, { onlyBuiltin, environment, name }] of graph.verticesOfType(vertex_1.VertexType.FunctionCall)) {
171
+ if (!name || onlyBuiltin) {
176
172
  continue;
177
173
  }
178
174
  // only the call environment counts!
@@ -218,7 +214,7 @@ function updateNestedFunctionCalls(graph, outEnvironment) {
218
214
  }
219
215
  }
220
216
  function prepareFunctionEnvironment(data) {
221
- let env = (0, environment_1.initializeCleanEnvironments)(data.builtInEnvironment.memory);
217
+ let env = data.ctx.env.makeCleanEnv();
222
218
  for (let i = 0; i < data.environment.level + 1 /* add another env */; i++) {
223
219
  env = (0, scoping_1.pushLocalEnvironment)(env);
224
220
  }
@@ -16,7 +16,7 @@ function processGet(name, args, rootId, data) {
16
16
  logger_1.dataflowLogger.warn(`symbol access with ${name.content} has not 1 argument, skipping`);
17
17
  return (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data, origin: 'default' }).information;
18
18
  }
19
- const retrieve = (0, unpack_argument_1.unpackArgument)(args[0]);
19
+ const retrieve = (0, unpack_argument_1.unpackNonameArg)(args[0]);
20
20
  if (retrieve === undefined || retrieve.type !== type_1.RType.String) {
21
21
  logger_1.dataflowLogger.warn(`symbol access with ${name.content} has not 1 argument, skipping`);
22
22
  return (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data, origin: 'default' }).information;
@@ -5,6 +5,8 @@ import type { ParentInformation } from '../../../../../../r-bridge/lang-4.x/ast/
5
5
  import type { RFunctionArgument } 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
  /**
8
- *
8
+ * Processes an if-then-else built-in function call.
9
+ * For example, `if(cond) thenExpr else elseExpr` and `if(cond) thenExpr`.
10
+ * The arguments will be either `[cond, thenExpr]` or `[cond, thenExpr, elseExpr]`.
9
11
  */
10
12
  export declare function processIfThenElse<OtherInfo>(name: RSymbol<OtherInfo & ParentInformation>, args: readonly RFunctionArgument<OtherInfo & ParentInformation>[], rootId: NodeId, data: DataflowProcessorInformation<OtherInfo & ParentInformation>): DataflowInformation;
@@ -10,18 +10,20 @@ const logger_1 = require("../../../../../logger");
10
10
  const edge_1 = require("../../../../../graph/edge");
11
11
  const append_1 = require("../../../../../environments/append");
12
12
  const identifier_1 = require("../../../../../environments/identifier");
13
- const environment_1 = require("../../../../../environments/environment");
14
13
  const general_1 = require("../../../../../eval/values/general");
15
14
  const alias_tracking_1 = require("../../../../../eval/resolve/alias-tracking");
15
+ const reference_to_maybe_1 = require("../../../../../environments/reference-to-maybe");
16
16
  /**
17
- *
17
+ * Processes an if-then-else built-in function call.
18
+ * For example, `if(cond) thenExpr else elseExpr` and `if(cond) thenExpr`.
19
+ * The arguments will be either `[cond, thenExpr]` or `[cond, thenExpr, elseExpr]`.
18
20
  */
19
21
  function processIfThenElse(name, args, rootId, data) {
20
22
  if (args.length !== 2 && args.length !== 3) {
21
23
  logger_1.dataflowLogger.warn(`If-then-else ${name.content} has something different from 2 or 3 arguments, skipping`);
22
24
  return (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data, origin: 'default' }).information;
23
25
  }
24
- const [condArg, thenArg, otherwiseArg] = args.map(e => (0, unpack_argument_1.unpackArgument)(e));
26
+ const [condArg, thenArg, otherwiseArg] = args.map(e => (0, unpack_argument_1.unpackNonameArg)(e));
25
27
  if (condArg === undefined || thenArg === undefined) {
26
28
  logger_1.dataflowLogger.warn(`If-then-else ${name.content} has empty condition or then case in ${JSON.stringify(args)}, skipping`);
27
29
  return (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data, origin: 'default' }).information;
@@ -37,7 +39,7 @@ function processIfThenElse(name, args, rootId, data) {
37
39
  let then;
38
40
  let makeThenMaybe = false;
39
41
  // we should defer this to the abstract interpretation
40
- const values = (0, alias_tracking_1.resolveIdToValue)(condArg?.info.id, { environment: data.environment, idMap: data.completeAst.idMap, resolve: data.ctx.config.solver.variables });
42
+ const values = (0, alias_tracking_1.resolveIdToValue)(condArg?.info.id, { environment: data.environment, idMap: data.completeAst.idMap, resolve: data.ctx.config.solver.variables, ctx: data.ctx });
41
43
  const conditionIsAlwaysFalse = (0, general_1.valueSetGuard)(values)?.elements.every(d => d.type === 'logical' && d.value === false) ?? false;
42
44
  const conditionIsAlwaysTrue = (0, general_1.valueSetGuard)(values)?.elements.every(d => d.type === 'logical' && d.value === true) ?? false;
43
45
  if (!conditionIsAlwaysFalse) {
@@ -77,10 +79,10 @@ function processIfThenElse(name, args, rootId, data) {
77
79
  const cdTrue = { id: rootId, when: true };
78
80
  const cdFalse = { id: rootId, when: false };
79
81
  // again within an if-then-else we consider all actives to be read
80
- const ingoing = cond.in.concat(makeThenMaybe ? (0, environment_1.makeAllMaybe)(then?.in, nextGraph, finalEnvironment, false, cdTrue) : then?.in ?? [], makeOtherwiseMaybe ? (0, environment_1.makeAllMaybe)(otherwise?.in, nextGraph, finalEnvironment, false, cdFalse) : otherwise?.in ?? [], cond.unknownReferences, makeThenMaybe ? (0, environment_1.makeAllMaybe)(then?.unknownReferences, nextGraph, finalEnvironment, false, cdTrue) : then?.unknownReferences ?? [], makeOtherwiseMaybe ? (0, environment_1.makeAllMaybe)(otherwise?.unknownReferences, nextGraph, finalEnvironment, false, cdFalse) : otherwise?.unknownReferences ?? []);
82
+ const ingoing = cond.in.concat(makeThenMaybe ? (0, reference_to_maybe_1.makeAllMaybe)(then?.in, nextGraph, finalEnvironment, false, cdTrue) : then?.in ?? [], makeOtherwiseMaybe ? (0, reference_to_maybe_1.makeAllMaybe)(otherwise?.in, nextGraph, finalEnvironment, false, cdFalse) : otherwise?.in ?? [], cond.unknownReferences, makeThenMaybe ? (0, reference_to_maybe_1.makeAllMaybe)(then?.unknownReferences, nextGraph, finalEnvironment, false, cdTrue) : then?.unknownReferences ?? [], makeOtherwiseMaybe ? (0, reference_to_maybe_1.makeAllMaybe)(otherwise?.unknownReferences, nextGraph, finalEnvironment, false, cdFalse) : otherwise?.unknownReferences ?? []);
81
83
  // we assign all with a maybe marker
82
84
  // we do not merge even if they appear in both branches because the maybe links will refer to different ids
83
- const outgoing = cond.out.concat((makeThenMaybe ? (0, environment_1.makeAllMaybe)(then?.out, nextGraph, finalEnvironment, true, cdTrue) : then?.out ?? []), (makeOtherwiseMaybe ? (0, environment_1.makeAllMaybe)(otherwise?.out, nextGraph, finalEnvironment, true, cdFalse) : otherwise?.out ?? []));
85
+ const outgoing = cond.out.concat((makeThenMaybe ? (0, reference_to_maybe_1.makeAllMaybe)(then?.out, nextGraph, finalEnvironment, true, cdTrue) : then?.out ?? []), (makeOtherwiseMaybe ? (0, reference_to_maybe_1.makeAllMaybe)(otherwise?.out, nextGraph, finalEnvironment, true, cdFalse) : otherwise?.out ?? []));
84
86
  (0, common_1.patchFunctionCall)({
85
87
  nextGraph,
86
88
  rootId,
@@ -15,7 +15,7 @@ function processLibrary(name, args, rootId, data) {
15
15
  logger_1.dataflowLogger.warn(`Currently only one-arg library-likes are allows (for ${name.content}), skipping`);
16
16
  return (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data, hasUnknownSideEffect: true, origin: 'default' }).information;
17
17
  }
18
- const nameToLoad = (0, unpack_argument_1.unpackArgument)(args[0]);
18
+ const nameToLoad = (0, unpack_argument_1.unpackNonameArg)(args[0]);
19
19
  if (nameToLoad === undefined || nameToLoad.type !== type_1.RType.Symbol) {
20
20
  logger_1.dataflowLogger.warn('No library name provided, skipping');
21
21
  return (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data, hasUnknownSideEffect: true, origin: 'default' }).information;
@@ -18,7 +18,7 @@ function processPipe(name, args, rootId, data) {
18
18
  logger_1.dataflowLogger.warn(`Pipe ${name.content} has something else than 2 arguments, skipping`);
19
19
  return information;
20
20
  }
21
- const [lhs, rhs] = args.map(e => (0, unpack_argument_1.unpackArgument)(e));
21
+ const [lhs, rhs] = args.map(e => (0, unpack_argument_1.unpackNonameArg)(e));
22
22
  (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.`);
23
23
  if (rhs.type !== type_1.RType.FunctionCall) {
24
24
  logger_1.dataflowLogger.warn(`Expected rhs of pipe to be a function call, but got ${rhs.type} instead.`);
@@ -21,7 +21,7 @@ function processRepeatLoop(name, args, rootId, data) {
21
21
  logger_1.dataflowLogger.warn(`Repeat-Loop ${name.content} does not have 1 argument, skipping`);
22
22
  return (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data, origin: 'default' }).information;
23
23
  }
24
- const unpacked = (0, unpack_argument_1.unpackArgument)(args[0]);
24
+ const unpacked = (0, unpack_argument_1.unpackNonameArg)(args[0]);
25
25
  const { information, processedArguments } = (0, known_call_handling_1.processKnownFunctionCall)({
26
26
  name,
27
27
  args: unpacked ? [unpacked] : args,
@@ -59,11 +59,11 @@ args, rootId, data, config) {
59
59
  data,
60
60
  rootId,
61
61
  name,
62
- argumentProcessResult: args.map(a => a === r_function_call_1.EmptyArgument ? undefined : { entryPoint: (0, unpack_argument_1.unpackArgument)(a)?.info.id }),
62
+ argumentProcessResult: args.map(a => a === r_function_call_1.EmptyArgument ? undefined : { entryPoint: (0, unpack_argument_1.unpackNonameArg)(a)?.info.id }),
63
63
  origin: 'builtin:replacement',
64
64
  link: config.assignRootId ? { origin: [config.assignRootId] } : undefined
65
65
  });
66
- const firstArg = (0, unpack_argument_1.unpackArgument)(args[0]);
66
+ const firstArg = (0, unpack_argument_1.unpackNonameArg)(args[0]);
67
67
  (0, unknown_replacement_1.handleReplacementOperator)({
68
68
  operator: name.content,
69
69
  target: firstArg?.lexeme,
@@ -80,7 +80,7 @@ args, rootId, data, config) {
80
80
  res.graph.addEdge(rootId, ref, edge_1.EdgeType.Reads);
81
81
  }
82
82
  }
83
- const fa = (0, unpack_argument_1.unpackArgument)(args[0]);
83
+ const fa = (0, unpack_argument_1.unpackNonameArg)(args[0]);
84
84
  if (!data.ctx.config.solver.pointerTracking && fa) {
85
85
  res = {
86
86
  ...res,
@@ -4,7 +4,6 @@ exports.processRm = processRm;
4
4
  const known_call_handling_1 = require("../known-call-handling");
5
5
  const r_function_call_1 = require("../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-function-call");
6
6
  const logger_1 = require("../../../../../logger");
7
- const remove_1 = require("../../../../../environments/remove");
8
7
  const type_1 = require("../../../../../../r-bridge/lang-4.x/ast/model/type");
9
8
  /**
10
9
  *
@@ -32,13 +31,16 @@ function processRm(name, args, rootId, data) {
32
31
  names.push(unpacked.content.str);
33
32
  }
34
33
  }
35
- let env = res.environment;
34
+ let env = res.environment.current;
36
35
  for (const name of names) {
37
- env = (0, remove_1.remove)(name, env, data.builtInEnvironment);
36
+ env = env.remove(name);
38
37
  }
39
38
  return {
40
39
  ...res,
41
- environment: env
40
+ environment: {
41
+ current: env,
42
+ level: res.environment.level
43
+ }
42
44
  };
43
45
  }
44
46
  //# sourceMappingURL=built-in-rm.js.map
@@ -148,7 +148,7 @@ function processSourceCall(name, args, rootId, data, config) {
148
148
  sourceFile = [(0, retriever_1.removeRQuotes)(sourceFileArgument.lexeme)];
149
149
  }
150
150
  else if (sourceFileArgument !== r_function_call_1.EmptyArgument) {
151
- const resolved = (0, general_1.valueSetGuard)((0, alias_tracking_1.resolveIdToValue)(sourceFileArgument.info.id, { environment: data.environment, idMap: data.completeAst.idMap, resolve: data.ctx.config.solver.variables }));
151
+ const resolved = (0, general_1.valueSetGuard)((0, alias_tracking_1.resolveIdToValue)(sourceFileArgument.info.id, { environment: data.environment, idMap: data.completeAst.idMap, resolve: data.ctx.config.solver.variables, ctx: data.ctx }));
152
152
  sourceFile = resolved?.elements.map(r => r.type === 'string' && (0, r_value_1.isValue)(r.value) ? r.value.str : undefined).filter(assert_1.isNotUndefined);
153
153
  }
154
154
  if (sourceFile && sourceFile.length === 1) {
@@ -8,11 +8,11 @@ const assert_1 = require("../../../../../../util/assert");
8
8
  const unpack_argument_1 = require("../argument/unpack-argument");
9
9
  const r_function_call_1 = require("../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-function-call");
10
10
  const logger_1 = require("../../../../../logger");
11
- const environment_1 = require("../../../../../environments/environment");
12
11
  const edge_1 = require("../../../../../graph/edge");
13
12
  const identifier_1 = require("../../../../../environments/identifier");
14
13
  const general_1 = require("../../../../../eval/values/general");
15
14
  const alias_tracking_1 = require("../../../../../eval/resolve/alias-tracking");
15
+ const reference_to_maybe_1 = require("../../../../../environments/reference-to-maybe");
16
16
  /**
17
17
  *
18
18
  */
@@ -21,13 +21,13 @@ function processWhileLoop(name, args, rootId, data) {
21
21
  logger_1.dataflowLogger.warn(`While-Loop ${name.content} does not have 2 arguments, skipping`);
22
22
  return (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data, origin: 'default' }).information;
23
23
  }
24
- const unpackedArgs = args.map(e => (0, unpack_argument_1.unpackArgument)(e));
24
+ const unpackedArgs = args.map(e => (0, unpack_argument_1.unpackNonameArg)(e));
25
25
  if (unpackedArgs.some(assert_1.isUndefined)) {
26
26
  logger_1.dataflowLogger.warn(`While-Loop ${name.content} has empty arguments in ${JSON.stringify(args)}, skipping`);
27
27
  return (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data, origin: 'default' }).information;
28
28
  }
29
29
  // we should defer this to the abstract interpretation
30
- const values = (0, alias_tracking_1.resolveIdToValue)(unpackedArgs[0]?.info.id, { environment: data.environment, idMap: data.completeAst.idMap, resolve: data.ctx.config.solver.variables });
30
+ const values = (0, alias_tracking_1.resolveIdToValue)(unpackedArgs[0]?.info.id, { environment: data.environment, idMap: data.completeAst.idMap, resolve: data.ctx.config.solver.variables, ctx: data.ctx });
31
31
  const conditionIsAlwaysFalse = (0, general_1.valueSetGuard)(values)?.elements.every(d => d.type === 'logical' && d.value === false) ?? false;
32
32
  //We don't care about the body if it never executes
33
33
  if (conditionIsAlwaysFalse) {
@@ -69,7 +69,7 @@ function processWhileLoop(name, args, rootId, data) {
69
69
  return condition;
70
70
  }
71
71
  const cdTrue = { id: name.info.id, when: true };
72
- const remainingInputs = (0, linker_1.linkInputs)((0, environment_1.makeAllMaybe)(body.unknownReferences, information.graph, information.environment, false, cdTrue).concat((0, environment_1.makeAllMaybe)(body.in, information.graph, information.environment, false, cdTrue)), information.environment, condition.in.concat(condition.unknownReferences), information.graph, true);
72
+ const remainingInputs = (0, linker_1.linkInputs)((0, reference_to_maybe_1.makeAllMaybe)(body.unknownReferences, information.graph, information.environment, false, cdTrue).concat((0, reference_to_maybe_1.makeAllMaybe)(body.in, information.graph, information.environment, false, cdTrue)), information.environment, condition.in.concat(condition.unknownReferences), information.graph, true);
73
73
  (0, linker_1.linkCircularRedefinitionsWithinALoop)(information.graph, (0, linker_1.produceNameSharedIdMap)((0, linker_1.findNonLocalReads)(information.graph, condition.in)), body.out);
74
74
  (0, linker_1.reapplyLoopExitPoints)(body.exitPoints, body.in.concat(body.out, body.unknownReferences));
75
75
  // as the while-loop always evaluates its condition
@@ -77,7 +77,7 @@ function processWhileLoop(name, args, rootId, data) {
77
77
  return {
78
78
  unknownReferences: [],
79
79
  in: [{ nodeId: name.info.id, name: name.lexeme, controlDependencies: originalDependency, type: identifier_1.ReferenceType.Function }, ...remainingInputs],
80
- out: condition.out.concat((0, environment_1.makeAllMaybe)(body.out, information.graph, information.environment, true, cdTrue)),
80
+ out: condition.out.concat((0, reference_to_maybe_1.makeAllMaybe)(body.out, information.graph, information.environment, true, cdTrue)),
81
81
  entryPoint: name.info.id,
82
82
  exitPoints: (0, info_1.filterOutLoopExitPoints)(body.exitPoints),
83
83
  graph: information.graph,
@@ -29,8 +29,7 @@ function forceVertexArgumentValueReferences(rootId, value, graph, env) {
29
29
  }
30
30
  }
31
31
  }
32
- const containedSubflowIn = graph.vertices(true)
33
- .filter(([, info]) => (0, vertex_1.isFunctionDefinitionVertex)(info))
32
+ const containedSubflowIn = graph.verticesOfType(vertex_1.VertexType.FunctionDefinition)
34
33
  .flatMap(([, info]) => info.subflow.in)
35
34
  .toArray();
36
35
  // try to resolve them against the current environment
@@ -122,7 +121,7 @@ function patchFunctionCall({ nextGraph, rootId, name, data, argumentProcessResul
122
121
  args: argumentProcessResult.map(arg => arg === undefined ? r_function_call_1.EmptyArgument : { nodeId: arg.entryPoint, controlDependencies: undefined, call: undefined, type: identifier_1.ReferenceType.Argument }),
123
122
  origin: [origin],
124
123
  link
125
- }, !nextGraph.hasVertex(rootId) || nextGraph.isRoot(rootId), true);
124
+ }, data.ctx.env.makeCleanEnv(), !nextGraph.hasVertex(rootId) || nextGraph.isRoot(rootId), true);
126
125
  for (const arg of argumentProcessResult) {
127
126
  if (arg) {
128
127
  nextGraph.addEdge(rootId, arg.entryPoint, edge_1.EdgeType.Argument);
@@ -52,7 +52,7 @@ function processKnownFunctionCall({ name, args, rootId, data, reverseOrder = fal
52
52
  args: reverseOrder ? callArgs.reverse() : callArgs,
53
53
  indicesCollection: indicesCollection,
54
54
  origin: origin === 'default' ? ['function'] : [origin]
55
- });
55
+ }, data.ctx.env.makeCleanEnv());
56
56
  if (hasUnknownSideEffect) {
57
57
  (0, unknown_side_effect_1.handleUnknownSideEffect)(finalGraph, data.environment, rootId);
58
58
  }
@@ -45,7 +45,7 @@ function processUnnamedFunctionCall(functionCall, data) {
45
45
  cds: data.controlDependencies,
46
46
  args: callArgs, // same reference
47
47
  origin: [exports.UnnamedFunctionCallOrigin]
48
- });
48
+ }, data.ctx.env.makeCleanEnv());
49
49
  let inIds = remainingReadInArgs;
50
50
  inIds.push({ nodeId: functionRootId, name: functionCallName, controlDependencies: data.controlDependencies, type: identifier_1.ReferenceType.Function });
51
51
  if (functionCall.calledFunction.type === type_1.RType.FunctionDefinition) {
@@ -34,7 +34,7 @@ function processFunctionArgument(argument, data) {
34
34
  tag: vertex_1.VertexType.Use,
35
35
  id: argument.info.id,
36
36
  cds: data.controlDependencies
37
- });
37
+ }, data.ctx.env.makeCleanEnv());
38
38
  entryPoint = argument.info.id;
39
39
  }
40
40
  const ingoingRefs = [...value?.unknownReferences ?? [], ...value?.in ?? [], ...(name === undefined ? [] : [...name.in])];
@@ -22,7 +22,7 @@ function processSymbol(symbol, data) {
22
22
  tag: vertex_1.VertexType.Use,
23
23
  id: symbol.info.id,
24
24
  cds: data.controlDependencies
25
- }),
25
+ }, data.ctx.env.makeCleanEnv()),
26
26
  entryPoint: symbol.info.id,
27
27
  exitPoints: [{ nodeId: symbol.info.id, type: 0 /* ExitPointType.Default */, controlDependencies: data.controlDependencies }]
28
28
  };
@@ -4,4 +4,4 @@ import type { RNodeWithParent } from '../../../r-bridge/lang-4.x/ast/model/proce
4
4
  /**
5
5
  *
6
6
  */
7
- export declare function processValue<OtherInfo>({ info: { id } }: RNodeWithParent, data: DataflowProcessorInformation<OtherInfo>): DataflowInformation;
7
+ export declare function processValue<OtherInfo>({ info: { id } }: RNodeWithParent, { controlDependencies, completeAst: { idMap }, ctx: { env }, environment }: DataflowProcessorInformation<OtherInfo>): DataflowInformation;
@@ -7,18 +7,18 @@ const identifier_1 = require("../../environments/identifier");
7
7
  /**
8
8
  *
9
9
  */
10
- function processValue({ info: { id } }, data) {
10
+ function processValue({ info: { id } }, { controlDependencies, completeAst: { idMap }, ctx: { env }, environment }) {
11
11
  return {
12
12
  unknownReferences: [],
13
- in: [{ nodeId: id, name: undefined, controlDependencies: data.controlDependencies, type: identifier_1.ReferenceType.Constant }],
13
+ in: [{ nodeId: id, name: undefined, controlDependencies, type: identifier_1.ReferenceType.Constant }],
14
14
  out: [],
15
- environment: data.environment,
16
- graph: new graph_1.DataflowGraph(data.completeAst.idMap).addVertex({
15
+ environment,
16
+ graph: new graph_1.DataflowGraph(idMap).addVertex({
17
17
  tag: vertex_1.VertexType.Value,
18
18
  id: id,
19
- cds: data.controlDependencies
20
- }),
21
- exitPoints: [{ nodeId: id, type: 0 /* ExitPointType.Default */, controlDependencies: data.controlDependencies }],
19
+ cds: controlDependencies
20
+ }, env.makeCleanEnv()),
21
+ exitPoints: [{ nodeId: id, type: 0 /* ExitPointType.Default */, controlDependencies }],
22
22
  entryPoint: id
23
23
  };
24
24
  }
@@ -3,7 +3,7 @@
3
3
  */
4
4
  import type { ControlDependency, DataflowInformation } from './info';
5
5
  import type { NormalizedAst, ParentInformation, RNodeWithParent } from '../r-bridge/lang-4.x/ast/model/processing/decorate';
6
- import type { IEnvironment, REnvironmentInformation } from './environments/environment';
6
+ import type { REnvironmentInformation } from './environments/environment';
7
7
  import type { RNode } from '../r-bridge/lang-4.x/ast/model/model';
8
8
  import type { KnownParserType, Parser } from '../r-bridge/parser';
9
9
  import type { FlowrAnalyzerContext } from '../project/context/flowr-analyzer-context';
@@ -31,10 +31,6 @@ export interface DataflowProcessorInformation<OtherInfo> {
31
31
  * The chain of control-flow {@link NodeId}s that lead to the current node (e.g., of known ifs).
32
32
  */
33
33
  readonly controlDependencies: ControlDependency[] | undefined;
34
- /**
35
- * The built-in environment
36
- */
37
- readonly builtInEnvironment: IEnvironment;
38
34
  /**
39
35
  * The flowr context used for environment seeding, files, and precision control, ...
40
36
  */
@@ -82,13 +82,14 @@ ${switchCodeAndGraph ? dfGraph : codeText}
82
82
  }
83
83
  /** returns resolved expected df graph */
84
84
  async function verifyExpectedSubgraph(parser, code, expectedSubgraph) {
85
+ const context = (0, flowr_analyzer_context_1.contextFromInput)(code);
85
86
  /* we verify that we get what we want first! */
86
87
  const info = await (0, default_pipelines_1.createDataflowPipeline)(parser, {
87
- context: (0, flowr_analyzer_context_1.contextFromInput)(code),
88
+ context: context,
88
89
  getId: (0, decorate_1.deterministicCountingIdGenerator)(0)
89
90
  }).allRemainingSteps();
90
91
  expectedSubgraph.setIdMap(info.normalize.idMap);
91
- expectedSubgraph = (0, resolve_graph_1.resolveDataflowGraph)(expectedSubgraph);
92
+ expectedSubgraph = (0, resolve_graph_1.resolveDataflowGraph)(expectedSubgraph, context);
92
93
  const report = (0, diff_dataflow_graph_1.diffOfDataflowGraphs)({ name: 'expected', graph: expectedSubgraph }, { name: 'got', graph: info.dataflow.graph }, {
93
94
  leftIsSubgraph: true
94
95
  });
@@ -64,12 +64,13 @@ ${(0, ast_1.normalizedAstToMermaid)(result.normalize.ast, prefix)}
64
64
  */
65
65
  async function verifyExpectedSubgraph(shell, code, expectedSubgraph) {
66
66
  /* we verify that we get what we want first! */
67
+ const context = (0, flowr_analyzer_context_1.contextFromInput)(code);
67
68
  const info = await (0, default_pipelines_1.createDataflowPipeline)(shell, {
68
- context: (0, flowr_analyzer_context_1.contextFromInput)(code),
69
+ context: context,
69
70
  getId: (0, decorate_1.deterministicCountingIdGenerator)(0)
70
71
  }).allRemainingSteps();
71
72
  expectedSubgraph.setIdMap(info.normalize.idMap);
72
- expectedSubgraph = (0, resolve_graph_1.resolveDataflowGraph)(expectedSubgraph);
73
+ expectedSubgraph = (0, resolve_graph_1.resolveDataflowGraph)(expectedSubgraph, context);
73
74
  const report = (0, diff_dataflow_graph_1.diffOfDataflowGraphs)({ name: 'expected', graph: expectedSubgraph }, { name: 'got', graph: info.dataflow.graph }, {
74
75
  leftIsSubgraph: true
75
76
  });
@@ -133,7 +133,7 @@ export interface FnElementInfo {
133
133
  export declare function printCodeOfElement({ program, info, dropLinesEnd, dropLinesStart, doNotAutoGobble, hideDefinedAt }: FnElementInfo, name: string): string;
134
134
  /**
135
135
  * Create a short link to a type in the documentation.
136
- * If you create a wiki, please refer to the functions provided by the {@link GeneralWikiContext}.
136
+ * If you create a wiki, please refer to the functions provided by the {@link GeneralDocContext}.
137
137
  * @param name - The name of the type, e.g. `MyType`, may include a container, e.g.,`MyContainer::MyType` (this works with function nestings too)
138
138
  * Use `:::` if you want to access a scoped function, but the name should be displayed without the scope
139
139
  * @param hierarchy - The hierarchy of types to search in
@@ -477,7 +477,7 @@ function printCodeOfElement({ program, info, dropLinesEnd = 0, dropLinesStart =
477
477
  const lines = code.replaceAll('\t', ' ').split(/\n/g);
478
478
  let gobble = Number.POSITIVE_INFINITY;
479
479
  for (const line of lines) {
480
- const match = line.match(/^(\s+)\S+/);
480
+ const match = line.match(/^(\s*)\S+/);
481
481
  if (match) {
482
482
  gobble = Math.min(gobble, match[1].length);
483
483
  }
@@ -523,7 +523,7 @@ function retrieveNode(name, hierarchy, fuzzy = false, type = undefined) {
523
523
  }
524
524
  /**
525
525
  * Create a short link to a type in the documentation.
526
- * If you create a wiki, please refer to the functions provided by the {@link GeneralWikiContext}.
526
+ * If you create a wiki, please refer to the functions provided by the {@link GeneralDocContext}.
527
527
  * @param name - The name of the type, e.g. `MyType`, may include a container, e.g.,`MyContainer::MyType` (this works with function nestings too)
528
528
  * Use `:::` if you want to access a scoped function, but the name should be displayed without the scope
529
529
  * @param hierarchy - The hierarchy of types to search in
@@ -26,6 +26,7 @@ const flowr_analyzer_plugin_defaults_1 = require("../project/plugins/flowr-analy
26
26
  const doc_maker_1 = require("./wiki-mk/doc-maker");
27
27
  const flowr_analyzer_rmd_file_plugin_1 = require("../project/plugins/file-plugins/notebooks/flowr-analyzer-rmd-file-plugin");
28
28
  const flowr_analyzer_plugin_1 = require("../project/plugins/flowr-analyzer-plugin");
29
+ const flowr_analyzer_environment_context_1 = require("../project/context/flowr-analyzer-environment-context");
29
30
  async function analyzerQuickExample() {
30
31
  const analyzer = await new flowr_analyzer_builder_1.FlowrAnalyzerBuilder()
31
32
  .setEngine('tree-sitter')
@@ -78,7 +79,8 @@ ${(0, doc_structure_1.collapsibleToc)({
78
79
  'Context Information': {
79
80
  'Files Context': undefined,
80
81
  'Loading Order Context': undefined,
81
- 'Dependencies Context': undefined
82
+ 'Dependencies Context': undefined,
83
+ 'Environment Context': undefined
82
84
  },
83
85
  'Caching': undefined
84
86
  })}
@@ -396,6 +398,17 @@ Probably the most important method is
396
398
  ${ctx.linkM(flowr_analyzer_dependencies_context_1.FlowrAnalyzerDependenciesContext, 'getDependency', { codeFont: true, realNameWrapper: 'i' })}
397
399
  that allows you to query for a specific dependency by name.
398
400
 
401
+ ${(0, doc_structure_1.section)('Environment Context', 3)}
402
+
403
+ Here is the structure of the ${ctx.link(flowr_analyzer_environment_context_1.FlowrAnalyzerEnvironmentContext)} that provides access to the built-in environment:
404
+
405
+ ${ctx.hierarchy(flowr_analyzer_environment_context_1.FlowrAnalyzerEnvironmentContext, { showImplSnippet: false })}
406
+
407
+ The environment context provides access to the built-in environment via
408
+ ${ctx.linkM(flowr_analyzer_environment_context_1.FlowrAnalyzerEnvironmentContext, 'makeCleanEnv', { codeFont: true, realNameWrapper: 'i' })}.
409
+ It also provides the empty built-in environment, which only contains primitives, via
410
+ ${ctx.linkM(flowr_analyzer_environment_context_1.FlowrAnalyzerEnvironmentContext, 'makeCleanEnvWithEmptyBuiltIns', { codeFont: true, realNameWrapper: 'i' })}.
411
+
399
412
  ${(0, doc_structure_1.section)('Caching', 2)}
400
413
 
401
414
  To speed up analyses, flowR provides a caching mechanism that stores intermediate results of the analysis.
@@ -195,7 +195,7 @@ However, in general, flowR may use any fitting handler as an origin. For example
195
195
  ${(0, doc_structure_1.details)('Example: Simple Function Call (unresolved)', await (async () => {
196
196
  const code = 'foo(x,3,y=3,)';
197
197
  const [text, info] = await (0, doc_dfg_1.printDfGraphForCode)(parser, code, { mark: new Set([8]), exposeResult: true });
198
- const callInfo = [...info.dataflow.graph.vertices(true)].find(([, vertex]) => vertex.tag === vertex_1.VertexType.FunctionCall && vertex.name === 'foo');
198
+ const callInfo = info.dataflow.graph.vertices(true).find(([, vertex]) => vertex.tag === vertex_1.VertexType.FunctionCall && vertex.name === 'foo');
199
199
  (0, assert_1.guard)(callInfo !== undefined, () => `Could not find call vertex for ${code}`);
200
200
  const [callId, callVert] = callInfo;
201
201
  const inverseMapReferenceTypes = Object.fromEntries(Object.entries(identifier_1.ReferenceType).map(([k, v]) => [v, k]));
@@ -308,7 +308,7 @@ Consider a case in which you have a built-in function (like the assignment opera
308
308
 
309
309
  ${await (async () => {
310
310
  const [text, info] = await (0, doc_dfg_1.printDfGraphForCode)(parser, 'x <- 2\nif(u) `<-` <- `*`\nx <- 3', { switchCodeAndGraph: true, mark: new Set([9, '9->0', '9->10']), exposeResult: true });
311
- const interestingUseOfAssignment = [...info.dataflow.graph.vertices(true)].find(([, vertex]) => vertex.id === 11);
311
+ const interestingUseOfAssignment = info.dataflow.graph.vertices(true).find(([, vertex]) => vertex.id === 11);
312
312
  (0, assert_1.guard)(interestingUseOfAssignment !== undefined, () => 'Could not find interesting assignment vertex for the code');
313
313
  const [id, interestingVertex] = interestingUseOfAssignment;
314
314
  const env = interestingVertex.environment;
@@ -333,7 +333,7 @@ Hence, trying to re-resolve the call using ${ctx.link(linker_1.getAllFunctionCal
333
333
  the following target ids: { \`${[...(0, linker_1.getAllFunctionCallTargets)(id, info.dataflow.graph)].join('`, `')}\` }.
334
334
  This way we know that the call may refer to the built-in assignment operator or to the multiplication.
335
335
  Similarly, trying to resolve the name with ${ctx.link(resolve_by_name_1.resolveByName)}\` using the environment attached to the call vertex (filtering for any reference type) returns (in a similar fashion):
336
- { \`${(0, resolve_by_name_1.resolveByName)(name, env)?.map(d => d.nodeId).join('`, `')}\` } (however, the latter will not trace aliases).
336
+ { \`${(0, resolve_by_name_1.resolveByNameAnyType)(name, env)?.map(d => d.nodeId).join('`, `')}\` } (however, the latter will not trace aliases).
337
337
 
338
338
  `;
339
339
  })()}
@@ -449,8 +449,7 @@ vertices of function definitions or not (e.g., \`${new graph_1.DataflowGraph(und
449
449
 
450
450
  ${(0, doc_structure_1.details)('Example: Nested Function Definitions', await (async () => {
451
451
  const [text, info] = await (0, doc_dfg_1.printDfGraphForCode)(parser, 'f <- function() { g <- function() 3 }', { mark: new Set([9, 6]), exposeResult: true });
452
- const definitions = info.dataflow.graph.vertices(true)
453
- .filter(([, vertex]) => vertex.tag === vertex_1.VertexType.FunctionDefinition)
452
+ const definitions = info.dataflow.graph.verticesOfType(vertex_1.VertexType.FunctionDefinition)
454
453
  .map(([id, vertex]) => `| \`${id}\` | { \`${[...vertex.subflow.graph].join('`, `')}\` } |`)
455
454
  .toArray();
456
455
  return `
@@ -14,7 +14,6 @@ class WikiFaq extends doc_maker_1.DocMaker {
14
14
  const faqs = (0, faqs_1.registerFaqs)();
15
15
  return `
16
16
  ${faqs.toMarkdown()}
17
-
18
17
  `.trim();
19
18
  }
20
19
  }
@@ -144,7 +144,7 @@ df[6, "value"]
144
144
  const certaintyText = `\`${(0, html_hover_over_1.textWithTooltip)(rule.info.certainty, certaintyDoc)}\``;
145
145
  if (format === 'short') {
146
146
  ruleExplanations.set(name, () => Promise.resolve(`
147
- **[${rule.info.name}](${doc_files_1.FlowrWikiBaseRef}/${getPageNameForLintingRule(name)}):** ${rule.info.description} [see ${(0, doc_types_1.shortLinkFile)(ruleType, types)}]\\
147
+ **[${rule.info.name}](${doc_files_1.FlowrWikiBaseRef}/${encodeURIComponent(getPageNameForLintingRule(name))}):** ${rule.info.description} [see ${(0, doc_types_1.shortLinkFile)(ruleType, types)}]\\
148
148
  ${tags}
149
149
 
150
150
  `.trim()));
@@ -16,8 +16,9 @@ const DefaultReplacementPatterns = [
16
16
  [/%%\s*\d*-+/g, ''],
17
17
  [/"[rR]": "\d+\.\d+\.\d+.*?"/g, ''],
18
18
  [/R\s*\d+\.\d+\.\d+/g, ''],
19
+ [/v\d+\.\d+\.\d+/g, ''],
19
20
  // async wrapper depends on whether the promise got forfilled already
20
- [/%20async%20/g, ' ']
21
+ [/async|%20/g, '']
21
22
  ];
22
23
  /**
23
24
  * Abstract base class for generating wiki files.
@@ -57,7 +57,7 @@ export declare const LintingRules: {
57
57
  };
58
58
  readonly 'seeded-randomness': {
59
59
  readonly createSearch: (config: import("./rules/seeded-randomness").SeededRandomnessConfig) => import("../search/flowr-search-builder").FlowrSearchBuilder<"all", ["with", "filter", "with"], import("../r-bridge/lang-4.x/ast/model/processing/decorate").ParentInformation, Promise<import("../search/flowr-search").FlowrSearchElements<import("../r-bridge/lang-4.x/ast/model/processing/decorate").ParentInformation, import("../search/flowr-search").FlowrSearchElement<import("../r-bridge/lang-4.x/ast/model/processing/decorate").ParentInformation>[]>>>;
60
- readonly processSearchResult: (elements: import("../search/flowr-search").FlowrSearchElements<import("../r-bridge/lang-4.x/ast/model/processing/decorate").ParentInformation, import("../search/flowr-search").FlowrSearchElement<import("../r-bridge/lang-4.x/ast/model/processing/decorate").ParentInformation>[]>, config: import("./rules/seeded-randomness").SeededRandomnessConfig, { dataflow }: {
60
+ readonly processSearchResult: (elements: import("../search/flowr-search").FlowrSearchElements<import("../r-bridge/lang-4.x/ast/model/processing/decorate").ParentInformation, import("../search/flowr-search").FlowrSearchElement<import("../r-bridge/lang-4.x/ast/model/processing/decorate").ParentInformation>[]>, config: import("./rules/seeded-randomness").SeededRandomnessConfig, { dataflow, analyzer }: {
61
61
  normalize: import("../r-bridge/lang-4.x/ast/model/processing/decorate").NormalizedAst;
62
62
  dataflow: import("../dataflow/info").DataflowInformation;
63
63
  cfg: import("../control-flow/control-flow-graph").ControlFlowInformation;
@@ -231,7 +231,7 @@ export declare const LintingRules: {
231
231
  readonly name: "Dataframe Access Validation";
232
232
  readonly tags: readonly [import("./linter-tags").LintingRuleTag.Bug, import("./linter-tags").LintingRuleTag.Usability, import("./linter-tags").LintingRuleTag.Reproducibility];
233
233
  readonly certainty: import("./linter-format").LintingRuleCertainty.BestEffort;
234
- readonly description: "Validates the existance of accessed columns and rows of dataframes.";
234
+ readonly description: "Validates the existence of accessed columns and rows of dataframes.";
235
235
  readonly defaultConfig: {
236
236
  readonly readLoadedData: false;
237
237
  };