@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
@@ -49,15 +49,15 @@ function buildQuickFix(str, filePath, wd) {
49
49
  }
50
50
  /** return all strings constructable by these functions */
51
51
  const PathFunctions = {
52
- 'file.path': (df, vtx, config) => {
53
- const fsep = (0, resolve_argument_1.getArgumentStringValue)(config.solver.variables, df, vtx, undefined, 'fsep', true);
52
+ 'file.path': (df, vtx, ctx) => {
53
+ const fsep = (0, resolve_argument_1.getArgumentStringValue)(ctx.config.solver.variables, df, vtx, undefined, 'fsep', true, ctx);
54
54
  // in the future we can access `.Platform$file.sep` here
55
55
  const sepValues = fsep?.values()?.flatMap(s => s.values().filter(assert_1.isNotUndefined)).toArray() ?? [path_1.default.sep];
56
56
  if (sepValues.some(s => s === dependencies_query_format_1.Unknown || (0, assert_1.isUndefined)(s))) {
57
57
  // if we have no fsep, we cannot construct a path
58
58
  return undefined;
59
59
  }
60
- const args = (0, resolve_argument_1.getArgumentStringValue)(config.solver.variables, df, vtx, 'unnamed', undefined, true);
60
+ const args = (0, resolve_argument_1.getArgumentStringValue)(ctx.config.solver.variables, df, vtx, 'unnamed', undefined, true, ctx);
61
61
  const argValues = args ? Array.from(args.values()).flatMap(v => [...v]) : [];
62
62
  if (!argValues || argValues.length === 0 || argValues.some(v => v === dependencies_query_format_1.Unknown || (0, assert_1.isUndefined)(v))) {
63
63
  // if we have no arguments, we cannot construct a path
@@ -139,7 +139,7 @@ exports.ABSOLUTE_PATH = {
139
139
  const dfNode = data.dataflow.graph.getVertex(node.info.id);
140
140
  if ((0, vertex_1.isFunctionCallVertex)(dfNode)) {
141
141
  const handler = PathFunctions[dfNode.name ?? ''];
142
- const strings = handler ? handler(data.dataflow.graph, dfNode, data.analyzer.flowrConfig) : [];
142
+ const strings = handler ? handler(data.dataflow.graph, dfNode, data.analyzer.inspectContext()) : [];
143
143
  if (strings) {
144
144
  return strings.filter(s => (0, strings_1.isAbsolutePath)(s, regex)).map(str => ({
145
145
  certainty: linter_format_1.LintingResultCertainty.Uncertain,
@@ -47,7 +47,7 @@ export declare const DATA_FRAME_ACCESS_VALIDATION: {
47
47
  readonly name: "Dataframe Access Validation";
48
48
  readonly tags: readonly [LintingRuleTag.Bug, LintingRuleTag.Usability, LintingRuleTag.Reproducibility];
49
49
  readonly certainty: LintingRuleCertainty.BestEffort;
50
- readonly description: "Validates the existance of accessed columns and rows of dataframes.";
50
+ readonly description: "Validates the existence of accessed columns and rows of dataframes.";
51
51
  readonly defaultConfig: {
52
52
  readonly readLoadedData: false;
53
53
  };
@@ -85,7 +85,7 @@ exports.DATA_FRAME_ACCESS_VALIDATION = {
85
85
  tags: [linter_tags_1.LintingRuleTag.Bug, linter_tags_1.LintingRuleTag.Usability, linter_tags_1.LintingRuleTag.Reproducibility],
86
86
  // this rule is unable to detect all cases of dataframe access, but sufficiently ensures returned results are valid
87
87
  certainty: linter_format_1.LintingRuleCertainty.BestEffort,
88
- description: 'Validates the existance of accessed columns and rows of dataframes.',
88
+ description: 'Validates the existence of accessed columns and rows of dataframes.',
89
89
  defaultConfig: { readLoadedData: false }
90
90
  }
91
91
  };
@@ -5,8 +5,8 @@ import type { FlowrSearchElement, FlowrSearchElements } from '../../search/flowr
5
5
  import type { NormalizedAst, ParentInformation } from '../../r-bridge/lang-4.x/ast/model/processing/decorate';
6
6
  import type { MergeableRecord } from '../../util/objects';
7
7
  import type { DataflowInformation } from '../../dataflow/info';
8
- import type { FlowrConfigOptions } from '../../config';
9
8
  import type { FunctionInfo } from '../../queries/catalog/dependencies-query/function-info/function-info';
9
+ import type { ReadonlyFlowrAnalysisProvider } from '../../project/flowr-analyzer';
10
10
  export interface FunctionsResult extends LintingResult {
11
11
  function: string;
12
12
  range: SourceRange;
@@ -41,6 +41,6 @@ export declare const functionFinderUtil: {
41
41
  requireArgumentValue(element: FlowrSearchElement<ParentInformation>, pool: readonly FunctionInfo[], data: {
42
42
  normalize: NormalizedAst;
43
43
  dataflow: DataflowInformation;
44
- config: FlowrConfigOptions;
44
+ analyzer: ReadonlyFlowrAnalysisProvider;
45
45
  }, requireValue: RegExp | string | undefined): boolean;
46
46
  };
@@ -65,7 +65,7 @@ exports.functionFinderUtil = {
65
65
  }
66
66
  const vert = data.dataflow.graph.getVertex(element.node.info.id);
67
67
  if ((0, vertex_1.isFunctionCallVertex)(vert)) {
68
- const args = (0, resolve_argument_1.getArgumentStringValue)(data.config.solver.variables, data.dataflow.graph, vert, info.argIdx, info.argName, info.resolveValue);
68
+ const args = (0, resolve_argument_1.getArgumentStringValue)(data.analyzer.flowrConfig.solver.variables, data.dataflow.graph, vert, info.argIdx, info.argName, info.resolveValue, data.analyzer.inspectContext());
69
69
  // we obtain all values, at least one of them has to trigger for the request
70
70
  const argValues = args ? args.values().flatMap(v => [...v]).filter(assert_1.isNotUndefined).toArray() : [];
71
71
  /* if there are no arguments we assume they may access the network, otherwise we check for the flag */
@@ -7,7 +7,7 @@ const linter_tags_1 = require("../linter-tags");
7
7
  const read_functions_1 = require("../../queries/catalog/dependencies-query/function-info/read-functions");
8
8
  exports.NETWORK_FUNCTIONS = {
9
9
  createSearch: (config) => function_finder_util_1.functionFinderUtil.createSearch(config.fns),
10
- processSearchResult: (e, c, d) => function_finder_util_1.functionFinderUtil.processSearchResult(e, c, d, es => es.filter(e => function_finder_util_1.functionFinderUtil.requireArgumentValue(e, read_functions_1.ReadFunctions, { config: d.analyzer.flowrConfig, dataflow: d.dataflow, normalize: d.normalize }, c.onlyTriggerWithArgument))),
10
+ processSearchResult: (e, c, d) => function_finder_util_1.functionFinderUtil.processSearchResult(e, c, d, es => es.filter(e => function_finder_util_1.functionFinderUtil.requireArgumentValue(e, read_functions_1.ReadFunctions, { analyzer: d.analyzer, dataflow: d.dataflow, normalize: d.normalize }, c.onlyTriggerWithArgument))),
11
11
  prettyPrint: function_finder_util_1.functionFinderUtil.prettyPrint('network operations'),
12
12
  info: {
13
13
  name: 'Network Functions',
@@ -31,7 +31,7 @@ export interface SeededRandomnessMeta extends MergeableRecord {
31
31
  }
32
32
  export declare const SEEDED_RANDOMNESS: {
33
33
  readonly createSearch: (config: 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>[]>>>;
34
- 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: SeededRandomnessConfig, { dataflow }: {
34
+ 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: SeededRandomnessConfig, { dataflow, analyzer }: {
35
35
  normalize: import("../../r-bridge/lang-4.x/ast/model/processing/decorate").NormalizedAst;
36
36
  dataflow: import("../../dataflow/info").DataflowInformation;
37
37
  cfg: import("../../control-flow/control-flow-graph").ControlFlowInformation;
@@ -31,7 +31,7 @@ exports.SEEDED_RANDOMNESS = {
31
31
  { callName: config.randomnessProducers.filter(p => p.type === 'function').map(p => p.name) },
32
32
  { callName: getDefaultAssignments().flatMap(b => b.names), cascadeIf: () => cascade_action_1.CascadeAction.Continue }
33
33
  ]),
34
- processSearchResult: (elements, config, { dataflow }) => {
34
+ processSearchResult: (elements, config, { dataflow, analyzer }) => {
35
35
  const assignmentProducers = new Set(config.randomnessProducers.filter(p => p.type == 'assignment').map(p => p.name));
36
36
  const assignmentArgIndexes = new Map(getDefaultAssignments().flatMap(a => a.names.map(n => ([n, a.config?.swapSourceAndTarget ? 1 : 0]))));
37
37
  const metadata = {
@@ -63,7 +63,7 @@ exports.SEEDED_RANDOMNESS = {
63
63
  let otherBranch = false;
64
64
  // function calls are already taken care of through the LastCall enrichment itself
65
65
  for (const f of func ?? []) {
66
- if (isConstantArgument(dataflow.graph, f, 0)) {
66
+ if (isConstantArgument(dataflow.graph, f, 0, analyzer.inspectContext())) {
67
67
  const fCds = new Set(f.cds).difference(cds);
68
68
  if (fCds.size <= 0 || (0, info_1.happensInEveryBranchSet)(fCds)) {
69
69
  metadata.callsWithFunctionProducers++;
@@ -83,7 +83,7 @@ exports.SEEDED_RANDOMNESS = {
83
83
  const dest = (0, graph_1.getReferenceOfArgument)(a.args[argIdx]);
84
84
  if (dest !== undefined && assignmentProducers.has((0, node_id_1.recoverName)(dest, dataflow.graph.idMap))) {
85
85
  // we either have arg index 0 or 1 for the assignmentProducers destination, so we select the assignment value as 1-argIdx here
86
- if (isConstantArgument(dataflow.graph, a, 1 - argIdx)) {
86
+ if (isConstantArgument(dataflow.graph, a, 1 - argIdx, analyzer.inspectContext())) {
87
87
  const aCds = new Set(a.cds).difference(cds);
88
88
  if (aCds.size <= 0 || (0, info_1.happensInEveryBranchSet)(aCds)) {
89
89
  metadata.callsWithAssignmentProducers++;
@@ -132,9 +132,9 @@ exports.SEEDED_RANDOMNESS = {
132
132
  function getDefaultAssignments() {
133
133
  return default_builtin_config_1.DefaultBuiltinConfig.filter(b => b.type === 'function' && b.processor == 'builtin:assignment');
134
134
  }
135
- function isConstantArgument(graph, call, argIndex) {
135
+ function isConstantArgument(graph, call, argIndex, ctx) {
136
136
  const args = call.args.filter(arg => arg !== r_function_call_1.EmptyArgument && !arg.name).map(graph_1.getReferenceOfArgument);
137
- const values = (0, general_1.valueSetGuard)((0, alias_tracking_1.resolveIdToValue)(args[argIndex], { graph: graph, resolve: config_1.VariableResolve.Alias }));
137
+ const values = (0, general_1.valueSetGuard)((0, alias_tracking_1.resolveIdToValue)(args[argIndex], { graph: graph, resolve: config_1.VariableResolve.Alias, ctx }));
138
138
  return values?.elements.every(v => v.type === 'number' ||
139
139
  v.type === 'logical' ||
140
140
  v.type === 'string' ||
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eagleoutice/flowr",
3
- "version": "2.6.3",
3
+ "version": "2.7.0",
4
4
  "description": "Static Dataflow Analyzer and Program Slicer for the R Programming Language",
5
5
  "types": "dist/src/index.d.ts",
6
6
  "repository": {
@@ -28,7 +28,6 @@
28
28
  "capabilities-markdown": "ts-node src/documentation/doc-capabilities.ts",
29
29
  "wiki": "ts-node src/cli/wiki.ts",
30
30
  "wiki:watch": "ts-node-dev src/cli/wiki.ts -- --keep-alive",
31
- "wiki:linter": "ts-node src/documentation/wiki-linter.ts",
32
31
  "build": "tsc --project .",
33
32
  "build-dev": "npm run build && npm run build:copy-wasm",
34
33
  "build:bundle-flowr": "npm run build && esbuild --bundle dist/src/cli/flowr.js --platform=node --tree-shaking=true --bundle --minify --external:clipboardy --target=node22 --outfile=dist/src/cli/flowr.min.js && npm run build:copy-wasm",
@@ -4,6 +4,8 @@ import { type FlowrAnalyzerPlugin, PluginType } from '../plugins/flowr-analyzer-
4
4
  import type { fileProtocol, RParseRequestFromFile, RParseRequests } from '../../r-bridge/retriever';
5
5
  import type { FlowrConfigOptions } from '../../config';
6
6
  import type { FlowrFileProvider } from './flowr-file';
7
+ import type { ReadOnlyFlowrAnalyzerEnvironmentContext } from './flowr-analyzer-environment-context';
8
+ import { FlowrAnalyzerEnvironmentContext } from './flowr-analyzer-environment-context';
7
9
  /**
8
10
  * This is a read-only interface to the {@link FlowrAnalyzerContext}.
9
11
  * It prevents you from modifying the context, but allows you to inspect it (which is probably what you want when using the {@link FlowrAnalyzer}).
@@ -18,6 +20,10 @@ export interface ReadOnlyFlowrAnalyzerContext {
18
20
  * The dependencies context provides access to the identified dependencies and their versions.
19
21
  */
20
22
  readonly deps: ReadOnlyFlowrAnalyzerDependenciesContext;
23
+ /**
24
+ * The environment context provides access to the environment information used during analysis.
25
+ */
26
+ readonly env: ReadOnlyFlowrAnalyzerEnvironmentContext;
21
27
  /**
22
28
  * The configuration options used by the analyzer.
23
29
  */
@@ -38,6 +44,7 @@ export interface ReadOnlyFlowrAnalyzerContext {
38
44
  export declare class FlowrAnalyzerContext implements ReadOnlyFlowrAnalyzerContext {
39
45
  readonly files: FlowrAnalyzerFilesContext;
40
46
  readonly deps: FlowrAnalyzerDependenciesContext;
47
+ readonly env: FlowrAnalyzerEnvironmentContext;
41
48
  readonly config: FlowrConfigOptions;
42
49
  constructor(config: FlowrConfigOptions, plugins: ReadonlyMap<PluginType, readonly FlowrAnalyzerPlugin[]>);
43
50
  /** delegate request addition */
@@ -11,6 +11,7 @@ const arrays_1 = require("../../util/collections/arrays");
11
11
  const retriever_1 = require("../../r-bridge/retriever");
12
12
  const config_1 = require("../../config");
13
13
  const flowr_file_1 = require("./flowr-file");
14
+ const flowr_analyzer_environment_context_1 = require("./flowr-analyzer-environment-context");
14
15
  /**
15
16
  * This summarizes the other context layers used by the {@link FlowrAnalyzer}.
16
17
  * Have a look at the attributes and layers listed below (e.g., {@link files} and {@link deps})
@@ -26,12 +27,14 @@ const flowr_file_1 = require("./flowr-file");
26
27
  class FlowrAnalyzerContext {
27
28
  files;
28
29
  deps;
30
+ env;
29
31
  config;
30
32
  constructor(config, plugins) {
31
33
  this.config = config;
32
34
  const loadingOrder = new flowr_analyzer_loading_order_context_1.FlowrAnalyzerLoadingOrderContext(this, plugins.get(flowr_analyzer_plugin_1.PluginType.LoadingOrder));
33
35
  this.files = new flowr_analyzer_files_context_1.FlowrAnalyzerFilesContext(loadingOrder, (plugins.get(flowr_analyzer_plugin_1.PluginType.ProjectDiscovery) ?? []), (plugins.get(flowr_analyzer_plugin_1.PluginType.FileLoad) ?? []));
34
36
  this.deps = new flowr_analyzer_dependencies_context_1.FlowrAnalyzerDependenciesContext(this, (plugins.get(flowr_analyzer_plugin_1.PluginType.DependencyIdentification) ?? []));
37
+ this.env = new flowr_analyzer_environment_context_1.FlowrAnalyzerEnvironmentContext(this);
35
38
  }
36
39
  /** delegate request addition */
37
40
  addRequests(requests) {
@@ -0,0 +1,47 @@
1
+ import type { FlowrAnalyzerContext } from './flowr-analyzer-context';
2
+ import type { IEnvironment, REnvironmentInformation } from '../../dataflow/environments/environment';
3
+ import type { DeepReadonly } from 'ts-essentials';
4
+ import type { Fingerprint } from '../../slicing/static/fingerprint';
5
+ /**
6
+ * This is the read-only interface to the {@link FlowrAnalyzerEnvironmentContext},
7
+ * which provides access to the built-in environment used during analysis.
8
+ */
9
+ export interface ReadOnlyFlowrAnalyzerEnvironmentContext {
10
+ /**
11
+ * Get the built-in environment used during analysis.
12
+ */
13
+ get builtInEnvironment(): DeepReadonly<IEnvironment>;
14
+ /**
15
+ * Get the empty built-in environment used during analysis.
16
+ * The empty built-in environment only contains primitive definitions.
17
+ */
18
+ get emptyBuiltInEnvironment(): DeepReadonly<IEnvironment>;
19
+ /**
20
+ * Create a new {@link REnvironmentInformation|environment} with the configured built-in environment as base.
21
+ */
22
+ makeCleanEnv(): REnvironmentInformation;
23
+ /**
24
+ * Get the fingerprint of the clean environment with the configured built-in environment as base.
25
+ */
26
+ getCleanEnvFingerprint(): Fingerprint;
27
+ /**
28
+ * Create a new {@link REnvironmentInformation|environment} with an empty built-in environment as base.
29
+ */
30
+ makeCleanEnvWithEmptyBuiltIns(): REnvironmentInformation;
31
+ }
32
+ /**
33
+ * This context is responsible for providing the built-in environment.
34
+ * It creates the built-in environment based on the configuration provided in the {@link FlowrAnalyzerContext}.
35
+ */
36
+ export declare class FlowrAnalyzerEnvironmentContext implements ReadOnlyFlowrAnalyzerEnvironmentContext {
37
+ readonly name = "flowr-analyzer-environment-context";
38
+ private readonly builtInEnv;
39
+ private readonly emptyBuiltInEnv;
40
+ private builtInEnvFingerprint;
41
+ constructor(ctx: FlowrAnalyzerContext);
42
+ get builtInEnvironment(): DeepReadonly<IEnvironment>;
43
+ get emptyBuiltInEnvironment(): DeepReadonly<IEnvironment>;
44
+ makeCleanEnv(): REnvironmentInformation;
45
+ getCleanEnvFingerprint(): Fingerprint;
46
+ makeCleanEnvWithEmptyBuiltIns(): REnvironmentInformation;
47
+ }
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FlowrAnalyzerEnvironmentContext = void 0;
4
+ const environment_1 = require("../../dataflow/environments/environment");
5
+ const built_in_config_1 = require("../../dataflow/environments/built-in-config");
6
+ const fingerprint_1 = require("../../slicing/static/fingerprint");
7
+ /**
8
+ * This context is responsible for providing the built-in environment.
9
+ * It creates the built-in environment based on the configuration provided in the {@link FlowrAnalyzerContext}.
10
+ */
11
+ class FlowrAnalyzerEnvironmentContext {
12
+ name = 'flowr-analyzer-environment-context';
13
+ builtInEnv;
14
+ emptyBuiltInEnv;
15
+ builtInEnvFingerprint;
16
+ constructor(ctx) {
17
+ const builtInsConfig = ctx.config.semantics.environment.overwriteBuiltIns;
18
+ const builtIns = (0, built_in_config_1.getBuiltInDefinitions)(builtInsConfig.definitions, builtInsConfig.loadDefaults);
19
+ this.builtInEnv = new environment_1.Environment(undefined, true);
20
+ this.builtInEnv.memory = builtIns.builtInMemory;
21
+ this.emptyBuiltInEnv = new environment_1.Environment(undefined, true);
22
+ this.emptyBuiltInEnv.memory = builtIns.emptyBuiltInMemory;
23
+ }
24
+ get builtInEnvironment() {
25
+ return this.builtInEnv;
26
+ }
27
+ get emptyBuiltInEnvironment() {
28
+ return this.emptyBuiltInEnv;
29
+ }
30
+ makeCleanEnv() {
31
+ return {
32
+ current: new environment_1.Environment(this.builtInEnv),
33
+ level: 0
34
+ };
35
+ }
36
+ getCleanEnvFingerprint() {
37
+ if (!this.builtInEnvFingerprint) {
38
+ this.builtInEnvFingerprint = (0, fingerprint_1.envFingerprint)(this.makeCleanEnv());
39
+ }
40
+ return this.builtInEnvFingerprint;
41
+ }
42
+ makeCleanEnvWithEmptyBuiltIns() {
43
+ return {
44
+ current: new environment_1.Environment(this.emptyBuiltInEnv),
45
+ level: 0
46
+ };
47
+ }
48
+ }
49
+ exports.FlowrAnalyzerEnvironmentContext = FlowrAnalyzerEnvironmentContext;
50
+ //# sourceMappingURL=flowr-analyzer-environment-context.js.map
@@ -192,10 +192,7 @@ async function executeCallContextQueries({ analyzer }, queries) {
192
192
  cfg = await analyzer.controlflow([], cfg_kind_1.CfgKind.WithDataflow);
193
193
  }
194
194
  const queriesWhichWantAliases = promotedQueries.filter(q => q.includeAliases);
195
- for (const [nodeId, info] of dataflow.graph.vertices(true)) {
196
- if (info.tag !== vertex_1.VertexType.FunctionCall) {
197
- continue;
198
- }
195
+ for (const [nodeId, info] of dataflow.graph.verticesOfType(vertex_1.VertexType.FunctionCall)) {
199
196
  /* if we have a vertex, and we check for aliased calls, we want to know if we define this as desired! */
200
197
  if (queriesWhichWantAliases.length > 0) {
201
198
  /*
@@ -26,9 +26,10 @@ exports.ControlFlowQueryDefinition = {
26
26
  }).description('The control flow query provides the control flow graph of the analysis, optionally simplified.'),
27
27
  flattenInvolvedNodes: (queryResults) => {
28
28
  const out = queryResults;
29
- return [...out.controlFlow.graph.vertices(true)]
29
+ return out.controlFlow.graph.vertices(true).entries()
30
30
  .filter(([, v]) => v.type !== control_flow_graph_1.CfgVertexType.Block)
31
- .map(v => v[0]);
31
+ .map(v => v[0])
32
+ .toArray();
32
33
  }
33
34
  };
34
35
  //# sourceMappingURL=control-flow-query-format.js.map
@@ -20,7 +20,7 @@ async function executeDataflowLensQuery({ analyzer }, queries) {
20
20
  nameRegex: '<-|<<-|->|->>|=|+|-|*|/|\\|>|function|repeat|if|next|break',
21
21
  blacklistWithName: true
22
22
  }
23
- });
23
+ }, analyzer.inspectContext().env.makeCleanEnv());
24
24
  const timing = Date.now() - now;
25
25
  return {
26
26
  '.meta': {
@@ -76,8 +76,8 @@ function getResults(queries, { dataflow, config, normalize }, results, kind, fun
76
76
  return kindEntries.flatMap(([name, results]) => results.flatMap(({ id, linkedIds }) => {
77
77
  const vertex = dataflow.graph.getVertex(id);
78
78
  const info = functionMap.get(name);
79
- const args = (0, resolve_argument_1.getArgumentStringValue)(config.solver.variables, dataflow.graph, vertex, info.argIdx, info.argName, info.resolveValue);
80
- const linkedArgs = collectValuesFromLinks(args, { dataflow, config }, linkedIds);
79
+ const args = (0, resolve_argument_1.getArgumentStringValue)(config.solver.variables, dataflow.graph, vertex, info.argIdx, info.argName, info.resolveValue, data.analyzer.inspectContext());
80
+ const linkedArgs = collectValuesFromLinks(args, { dataflow, config, ctx: data.analyzer.inspectContext() }, linkedIds);
81
81
  const linked = dropInfoOnLinkedIds(linkedIds);
82
82
  const foundValues = linkedArgs ?? args;
83
83
  if (!foundValues) {
@@ -97,7 +97,7 @@ function getResults(queries, { dataflow, config, normalize }, results, kind, fun
97
97
  (0, assert_1.guard)('mode' in (info.additionalArgs ?? {}), 'Need additional argument mode when checking for mode');
98
98
  const margs = info.additionalArgs?.mode;
99
99
  (0, assert_1.guard)(margs, 'Need additional argument mode when checking for mode');
100
- const modeArgs = (0, resolve_argument_1.getArgumentStringValue)(config.solver.variables, dataflow.graph, vertex, margs.argIdx, margs.argName, margs.resolveValue);
100
+ const modeArgs = (0, resolve_argument_1.getArgumentStringValue)(config.solver.variables, dataflow.graph, vertex, margs.argIdx, margs.argName, margs.resolveValue, data?.analyzer.inspectContext());
101
101
  const modeValues = modeArgs?.values().flatMap(v => [...v]) ?? [];
102
102
  if (info.ignoreIf === 'mode-only-read' && modeValues.every(m => m && readOnlyModes.has(m))) {
103
103
  // all modes are read-only, so we can ignore this
@@ -159,7 +159,7 @@ function collectValuesFromLinks(args, data, linkedIds) {
159
159
  if (vertex === undefined || vertex.tag !== vertex_1.VertexType.FunctionCall) {
160
160
  continue;
161
161
  }
162
- const args = (0, resolve_argument_1.getArgumentStringValue)(data.config.solver.variables, data.dataflow.graph, vertex, info.argIdx, info.argName, info.resolveValue);
162
+ const args = (0, resolve_argument_1.getArgumentStringValue)(data.config.solver.variables, data.dataflow.graph, vertex, info.argIdx, info.argName, info.resolveValue, data.ctx);
163
163
  if (args === undefined) {
164
164
  continue;
165
165
  }
@@ -1,6 +1,6 @@
1
1
  import type { BasicQueryData } from '../../base-query-format';
2
2
  import type { DfShapeQuery, DfShapeQueryResult } from './df-shape-query-format';
3
3
  /**
4
- * Executes the given dataframe shape queries using the provided analyzer.
4
+ * Executes the given data frame shape queries using the provided analyzer.
5
5
  */
6
6
  export declare function executeDfShapeQuery({ analyzer }: BasicQueryData, queries: readonly DfShapeQuery[]): Promise<DfShapeQueryResult>;
@@ -5,7 +5,7 @@ const shape_inference_1 = require("../../../abstract-interpretation/data-frame/s
5
5
  const parse_1 = require("../../../slicing/criterion/parse");
6
6
  const log_1 = require("../../../util/log");
7
7
  /**
8
- * Executes the given dataframe shape queries using the provided analyzer.
8
+ * Executes the given data frame shape queries using the provided analyzer.
9
9
  */
10
10
  async function executeDfShapeQuery({ analyzer }, queries) {
11
11
  if (queries.length !== 1 && queries.some(query => query.criterion === undefined)) {
@@ -1,11 +1,11 @@
1
+ import Joi from 'joi';
1
2
  import { type DataFrameDomain, DataFrameStateDomain } from '../../../abstract-interpretation/data-frame/dataframe-domain';
3
+ import type { ReplOutput } from '../../../cli/repl/commands/repl-main';
4
+ import type { FlowrConfigOptions } from '../../../config';
5
+ import type { SingleSlicingCriterion } from '../../../slicing/criterion/parse';
2
6
  import type { BaseQueryFormat, BaseQueryResult } from '../../base-query-format';
3
7
  import type { ParsedQueryLine } from '../../query';
4
8
  import { executeDfShapeQuery } from './df-shape-query-executor';
5
- import type { SingleSlicingCriterion } from '../../../slicing/criterion/parse';
6
- import type { ReplOutput } from '../../../cli/repl/commands/repl-main';
7
- import type { FlowrConfigOptions } from '../../../config';
8
- import Joi from 'joi';
9
9
  /** Infer the shape of data frames using abstract interpretation. */
10
10
  export interface DfShapeQuery extends BaseQueryFormat {
11
11
  readonly type: 'df-shape';
@@ -4,12 +4,12 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.DfShapeQueryDefinition = void 0;
7
+ const joi_1 = __importDefault(require("joi"));
7
8
  const dataframe_domain_1 = require("../../../abstract-interpretation/data-frame/dataframe-domain");
9
+ const slice_query_parser_1 = require("../../../cli/repl/parser/slice-query-parser");
8
10
  const ansi_1 = require("../../../util/text/ansi");
9
11
  const time_1 = require("../../../util/text/time");
10
12
  const df_shape_query_executor_1 = require("./df-shape-query-executor");
11
- const slice_query_parser_1 = require("../../../cli/repl/parser/slice-query-parser");
12
- const joi_1 = __importDefault(require("joi"));
13
13
  function dfShapeQueryLineParser(_output, line, _config) {
14
14
  const criterion = (0, slice_query_parser_1.sliceCriterionParser)(line[0]);
15
15
  return {
@@ -32,11 +32,11 @@ async function executeHigherOrderQuery({ analyzer }, queries) {
32
32
  }
33
33
  }
34
34
  const graph = (await analyzer.dataflow()).graph;
35
- const fns = graph.vertices(true)
36
- .filter(([, v]) => (0, vertex_1.isFunctionDefinitionVertex)(v) && (filterFor.size === 0 || filterFor.has(v.id)));
35
+ const fns = graph.verticesOfType(vertex_1.VertexType.FunctionDefinition)
36
+ .filter(([, v]) => filterFor.size === 0 || filterFor.has(v.id));
37
37
  const result = {};
38
38
  for (const [id,] of fns) {
39
- result[id] = (0, higher_order_function_1.isHigherOrder)(id, graph);
39
+ result[id] = (0, higher_order_function_1.isHigherOrder)(id, graph, analyzer.inspectContext());
40
40
  }
41
41
  return {
42
42
  '.meta': {
@@ -26,7 +26,7 @@ async function executeResolveValueQuery({ analyzer }, queries) {
26
26
  }
27
27
  const values = query.criteria
28
28
  .map(criteria => (0, parse_1.slicingCriterionToId)(criteria, ast.idMap))
29
- .flatMap(ident => (0, alias_tracking_1.resolveIdToValue)(ident, { graph, full: true, idMap: ast.idMap, resolve: analyzer.flowrConfig.solver.variables }));
29
+ .flatMap(ident => (0, alias_tracking_1.resolveIdToValue)(ident, { graph, full: true, idMap: ast.idMap, resolve: analyzer.flowrConfig.solver.variables, ctx: analyzer.inspectContext() }));
30
30
  results[key] = {
31
31
  values: values
32
32
  };
@@ -30,7 +30,7 @@ async function executeStaticSliceQuery({ analyzer }, queries) {
30
30
  }
31
31
  const { criteria, noReconstruction, noMagicComments } = query;
32
32
  const sliceStart = Date.now();
33
- const slice = (0, static_slicer_1.staticSlice)(await analyzer.dataflow(), await analyzer.normalize(), criteria, query.direction ?? _00_slice_1.SliceDirection.Backward, analyzer.flowrConfig.solver.slicer?.threshold);
33
+ const slice = (0, static_slicer_1.staticSlice)(analyzer.inspectContext(), await analyzer.dataflow(), await analyzer.normalize(), criteria, query.direction ?? _00_slice_1.SliceDirection.Backward, analyzer.flowrConfig.solver.slicer?.threshold);
34
34
  const sliceEnd = Date.now();
35
35
  if (noReconstruction) {
36
36
  results[key] = { slice: { ...slice, '.meta': { timing: sliceEnd - sliceStart } } };
@@ -6,11 +6,12 @@ import type { REnvironmentInformation } from '../../dataflow/environments/enviro
6
6
  import { type DataflowGraph, type OutgoingEdges } from '../../dataflow/graph/graph';
7
7
  import type { NodeId } from '../../r-bridge/lang-4.x/ast/model/processing/node-id';
8
8
  import type { DataflowInformation } from '../../dataflow/info';
9
+ import type { ReadOnlyFlowrAnalyzerContext } from '../../project/context/flowr-analyzer-context';
9
10
  /**
10
11
  * Returns the function call targets (definitions) by the given caller
11
12
  */
12
- export declare function getAllFunctionCallTargets(dataflowGraph: DataflowGraph, callerInfo: DataflowGraphVertexFunctionCall, baseEnvironment: REnvironmentInformation, queue: VisitingQueue): [Set<DataflowGraphVertexInfo>, REnvironmentInformation];
13
+ export declare function getAllFunctionCallTargets(dataflowGraph: DataflowGraph, callerInfo: DataflowGraphVertexFunctionCall, baseEnvironment: REnvironmentInformation, queue: VisitingQueue, ctx: ReadOnlyFlowrAnalyzerContext): [Set<DataflowGraphVertexInfo>, REnvironmentInformation];
13
14
  /** returns the new threshold hit count */
14
- export declare function sliceForCall(current: NodeToSlice, callerInfo: DataflowGraphVertexFunctionCall, dataflowInformation: DataflowInformation, queue: VisitingQueue): void;
15
+ export declare function sliceForCall(current: NodeToSlice, callerInfo: DataflowGraphVertexFunctionCall, dataflowInformation: DataflowInformation, queue: VisitingQueue, ctx: ReadOnlyFlowrAnalyzerContext): void;
15
16
  /** Returns true if we found at least one return edge */
16
17
  export declare function handleReturns(from: NodeId, queue: VisitingQueue, currentEdges: OutgoingEdges, baseEnvFingerprint: Fingerprint, baseEnvironment: REnvironmentInformation): boolean;
@@ -16,12 +16,12 @@ const static_slicer_1 = require("./static-slicer");
16
16
  /**
17
17
  * Returns the function call targets (definitions) by the given caller
18
18
  */
19
- function getAllFunctionCallTargets(dataflowGraph, callerInfo, baseEnvironment, queue) {
19
+ function getAllFunctionCallTargets(dataflowGraph, callerInfo, baseEnvironment, queue, ctx) {
20
20
  // bind with call-local environments during slicing
21
21
  const outgoingEdges = dataflowGraph.get(callerInfo.id, true);
22
22
  (0, assert_1.guard)(outgoingEdges !== undefined, () => `outgoing edges of id: ${callerInfo.id} must be in graph but can not be found, keep in slice to be sure`);
23
23
  // lift baseEnv on the same level
24
- const activeEnvironment = (0, built_in_function_definition_1.retrieveActiveEnvironment)(callerInfo.environment, baseEnvironment);
24
+ const activeEnvironment = (0, built_in_function_definition_1.retrieveActiveEnvironment)(callerInfo.environment, baseEnvironment, ctx);
25
25
  const name = callerInfo.name;
26
26
  (0, assert_1.guard)(name !== undefined, () => `name of id: ${callerInfo.id} can not be found in id map`);
27
27
  const functionCallDefs = (0, resolve_by_name_1.resolveByName)(name, activeEnvironment, identifier_1.ReferenceType.Unknown)?.filter(d => !(0, built_in_1.isBuiltIn)(d.definedAt))?.map(d => d.nodeId) ?? [];
@@ -59,9 +59,9 @@ function linkCallTargets(onlyForSideEffects, functionCallTargets, activeEnvironm
59
59
  }
60
60
  }
61
61
  /** returns the new threshold hit count */
62
- function sliceForCall(current, callerInfo, dataflowInformation, queue) {
62
+ function sliceForCall(current, callerInfo, dataflowInformation, queue, ctx) {
63
63
  const baseEnvironment = current.baseEnvironment;
64
- const [functionCallTargets, activeEnvironment] = getAllFunctionCallTargets(dataflowInformation.graph, callerInfo, current.baseEnvironment, queue);
64
+ const [functionCallTargets, activeEnvironment] = getAllFunctionCallTargets(dataflowInformation.graph, callerInfo, current.baseEnvironment, queue, ctx);
65
65
  const activeEnvironmentFingerprint = (0, fingerprint_1.envFingerprint)(activeEnvironment);
66
66
  if (functionCallTargets.size === 0) {
67
67
  /*
@@ -7,11 +7,13 @@ import { type REnvironmentInformation } from '../../dataflow/environments/enviro
7
7
  import type { NodeId } from '../../r-bridge/lang-4.x/ast/model/processing/node-id';
8
8
  import { SliceDirection } from '../../core/steps/all/static-slicing/00-slice';
9
9
  import type { DataflowInformation } from '../../dataflow/info';
10
+ import type { ReadOnlyFlowrAnalyzerContext } from '../../project/context/flowr-analyzer-context';
10
11
  export declare const slicerLogger: import("tslog").Logger<import("tslog").ILogObj>;
11
12
  /**
12
13
  * This returns the ids to include in the static slice of the given type, when slicing with the given seed id's (must be at least one).
13
14
  * <p>
14
15
  * The returned ids can be used to {@link reconstructToCode|reconstruct the slice to R code}.
16
+ * @param ctx - The analyzer context used for slicing.
15
17
  * @param info - The dataflow information used for slicing.
16
18
  * @param idMap - The mapping from node ids to their information in the AST.
17
19
  * @param criteria - The criteria to slice on.
@@ -19,7 +21,7 @@ export declare const slicerLogger: import("tslog").Logger<import("tslog").ILogOb
19
21
  * @param threshold - The maximum number of nodes to visit in the graph. If the threshold is reached, the slice will side with inclusion and drop its minimal guarantee. The limit ensures that the algorithm halts.
20
22
  * @param cache - A cache to store the results of the slice. If provided, the slice may use this cache to speed up the slicing process.
21
23
  */
22
- export declare function staticSlice(info: DataflowInformation, { idMap }: NormalizedAst, criteria: SlicingCriteria, direction: SliceDirection, threshold?: number, cache?: Map<Fingerprint, Set<NodeId>>): Readonly<SliceResult>;
24
+ export declare function staticSlice(ctx: ReadOnlyFlowrAnalyzerContext, info: DataflowInformation, { idMap }: NormalizedAst, criteria: SlicingCriteria, direction: SliceDirection, threshold?: number, cache?: Map<Fingerprint, Set<NodeId>>): Readonly<SliceResult>;
23
25
  /**
24
26
  * Updates the potential addition for the given target node in the visiting queue.
25
27
  * This describes vertices that might be added *if* another path reaches them.
@@ -5,11 +5,9 @@ exports.staticSlice = staticSlice;
5
5
  exports.updatePotentialAddition = updatePotentialAddition;
6
6
  const assert_1 = require("../../util/assert");
7
7
  const log_1 = require("../../util/log");
8
- const fingerprint_1 = require("./fingerprint");
9
8
  const visiting_queue_1 = require("./visiting-queue");
10
9
  const slice_call_1 = require("./slice-call");
11
10
  const parse_1 = require("../criterion/parse");
12
- const environment_1 = require("../../dataflow/environments/environment");
13
11
  const vertex_1 = require("../../dataflow/graph/vertex");
14
12
  const edge_1 = require("../../dataflow/graph/edge");
15
13
  const _00_slice_1 = require("../../core/steps/all/static-slicing/00-slice");
@@ -19,6 +17,7 @@ exports.slicerLogger = log_1.log.getSubLogger({ name: 'slicer' });
19
17
  * This returns the ids to include in the static slice of the given type, when slicing with the given seed id's (must be at least one).
20
18
  * <p>
21
19
  * The returned ids can be used to {@link reconstructToCode|reconstruct the slice to R code}.
20
+ * @param ctx - The analyzer context used for slicing.
22
21
  * @param info - The dataflow information used for slicing.
23
22
  * @param idMap - The mapping from node ids to their information in the AST.
24
23
  * @param criteria - The criteria to slice on.
@@ -26,21 +25,21 @@ exports.slicerLogger = log_1.log.getSubLogger({ name: 'slicer' });
26
25
  * @param threshold - The maximum number of nodes to visit in the graph. If the threshold is reached, the slice will side with inclusion and drop its minimal guarantee. The limit ensures that the algorithm halts.
27
26
  * @param cache - A cache to store the results of the slice. If provided, the slice may use this cache to speed up the slicing process.
28
27
  */
29
- function staticSlice(info, { idMap }, criteria, direction, threshold = 75, cache) {
28
+ function staticSlice(ctx, info, { idMap }, criteria, direction, threshold = 75, cache) {
30
29
  (0, assert_1.guard)(criteria.length > 0, 'must have at least one seed id to calculate slice');
31
30
  const decodedCriteria = (0, parse_1.convertAllSlicingCriteriaToIds)(criteria, idMap);
32
31
  (0, log_1.expensiveTrace)(exports.slicerLogger, () => `calculating ${direction} slice for ${decodedCriteria.length} seed criteria: ${decodedCriteria.map(s => JSON.stringify(s)).join(', ')}`);
33
32
  let { graph } = info;
34
33
  if (direction === _00_slice_1.SliceDirection.Forward) {
35
- graph = (0, invert_dfg_1.invertDfg)(graph);
34
+ graph = (0, invert_dfg_1.invertDfg)(graph, ctx.env.makeCleanEnv());
36
35
  }
37
36
  const queue = new visiting_queue_1.VisitingQueue(threshold, cache);
38
37
  let minNesting = Number.MAX_SAFE_INTEGER;
39
38
  const sliceSeedIds = new Set();
40
39
  // every node ships the call environment which registers the calling environment
41
40
  {
42
- const emptyEnv = (0, environment_1.initializeCleanEnvironments)();
43
- const basePrint = (0, fingerprint_1.envFingerprint)(emptyEnv);
41
+ const emptyEnv = ctx.env.makeCleanEnv();
42
+ const basePrint = ctx.env.getCleanEnvFingerprint();
44
43
  for (const { id: startId } of decodedCriteria) {
45
44
  queue.add(startId, emptyEnv, basePrint, false);
46
45
  // retrieve the minimum nesting of all nodes to only add control dependencies if they are "part" of the current execution
@@ -77,7 +76,7 @@ function staticSlice(info, { idMap }, criteria, direction, threshold = 75, cache
77
76
  }
78
77
  if (!onlyForSideEffects) {
79
78
  if (currentVertex.tag === vertex_1.VertexType.FunctionCall && !currentVertex.onlyBuiltin) {
80
- (0, slice_call_1.sliceForCall)(current, currentVertex, info, queue);
79
+ (0, slice_call_1.sliceForCall)(current, currentVertex, info, queue, ctx);
81
80
  }
82
81
  const ret = (0, slice_call_1.handleReturns)(id, queue, currentEdges, baseEnvFingerprint, baseEnvironment);
83
82
  if (ret) {
@@ -23,7 +23,7 @@ function visitIfThenElse(info, input) {
23
23
  (0, visitor_1.visitAst)(input.normalizedRAst.ast.files.map(f => f.root), node => {
24
24
  if (node.type !== type_1.RType.IfThenElse) {
25
25
  if (node.type === type_1.RType.FunctionCall && node.named && node.functionName.content === 'switch') {
26
- const initialArg = (0, unpack_argument_1.unpackArgument)(node.arguments[0]);
26
+ const initialArg = (0, unpack_argument_1.unpackNonameArg)(node.arguments[0]);
27
27
  if (initialArg) {
28
28
  info.switchCase = (0, common_syntax_probability_1.updateCommonSyntaxTypeCounts)(info.switchCase, initialArg);
29
29
  }
@@ -84,7 +84,7 @@ function visitCalls(info, input) {
84
84
  hasCallsEdge ? 1 : 0
85
85
  ]);
86
86
  }
87
- classifyArguments(node.arguments.map(e => (0, unpack_argument_1.unpackArgument)(e)), info.args);
87
+ classifyArguments(node.arguments.map(e => (0, unpack_argument_1.unpackNonameArg)(e)), info.args);
88
88
  calls.push(node);
89
89
  }, node => {
90
90
  // drop again :D