@eagleoutice/flowr 2.9.1 → 2.9.3

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 (80) hide show
  1. package/README.md +21 -21
  2. package/core/print/slice-diff-ansi.js +3 -3
  3. package/dataflow/environments/built-in.d.ts +10 -1
  4. package/dataflow/environments/default-builtin-config.d.ts +1 -0
  5. package/dataflow/environments/default-builtin-config.js +1 -1
  6. package/dataflow/eval/resolve/alias-tracking.d.ts +8 -8
  7. package/dataflow/eval/resolve/alias-tracking.js +33 -34
  8. package/dataflow/eval/resolve/resolve-argument.js +2 -2
  9. package/dataflow/eval/resolve/resolve.d.ts +7 -41
  10. package/dataflow/eval/resolve/resolve.js +24 -54
  11. package/dataflow/extractor.js +2 -2
  12. package/dataflow/graph/dataflowgraph-builder.d.ts +3 -2
  13. package/dataflow/graph/dataflowgraph-builder.js +4 -3
  14. package/dataflow/graph/diff-dataflow-graph.d.ts +1 -1
  15. package/dataflow/graph/diff-dataflow-graph.js +5 -1
  16. package/dataflow/graph/graph.d.ts +66 -10
  17. package/dataflow/graph/graph.js +87 -30
  18. package/dataflow/graph/vertex.d.ts +11 -1
  19. package/dataflow/internal/linker.d.ts +1 -1
  20. package/dataflow/internal/linker.js +12 -4
  21. package/dataflow/internal/process/functions/call/argument/make-argument.js +1 -2
  22. package/dataflow/internal/process/functions/call/built-in/built-in-assignment.d.ts +2 -0
  23. package/dataflow/internal/process/functions/call/built-in/built-in-assignment.js +10 -2
  24. package/dataflow/internal/process/functions/call/built-in/built-in-function-definition.js +4 -0
  25. package/dataflow/internal/process/functions/call/built-in/built-in-register-hook.js +2 -2
  26. package/dataflow/internal/process/functions/call/built-in/built-in-replacement.js +3 -3
  27. package/dataflow/internal/process/functions/call/built-in/built-in-s-seven-new-generic.js +21 -15
  28. package/dataflow/internal/process/functions/call/built-in/built-in-s-three-dispatch.js +1 -1
  29. package/documentation/doc-util/doc-search.js +2 -2
  30. package/documentation/wiki-dataflow-graph.js +8 -4
  31. package/linter/linter-executor.js +1 -2
  32. package/linter/linter-format.d.ts +37 -11
  33. package/linter/linter-format.js +59 -16
  34. package/linter/linter-rules.d.ts +8 -23
  35. package/linter/rules/absolute-path.d.ts +2 -2
  36. package/linter/rules/absolute-path.js +6 -7
  37. package/linter/rules/dataframe-access-validation.d.ts +1 -1
  38. package/linter/rules/dataframe-access-validation.js +3 -4
  39. package/linter/rules/dead-code.d.ts +2 -2
  40. package/linter/rules/dead-code.js +5 -6
  41. package/linter/rules/deprecated-functions.d.ts +4 -7
  42. package/linter/rules/file-path-validity.d.ts +2 -2
  43. package/linter/rules/file-path-validity.js +9 -6
  44. package/linter/rules/function-finder-util.d.ts +8 -11
  45. package/linter/rules/function-finder-util.js +21 -12
  46. package/linter/rules/naming-convention.d.ts +4 -11
  47. package/linter/rules/naming-convention.js +10 -10
  48. package/linter/rules/network-functions.d.ts +5 -8
  49. package/linter/rules/network-functions.js +14 -1
  50. package/linter/rules/seeded-randomness.d.ts +3 -3
  51. package/linter/rules/seeded-randomness.js +7 -7
  52. package/linter/rules/unused-definition.d.ts +2 -2
  53. package/linter/rules/unused-definition.js +13 -14
  54. package/linter/rules/useless-loop.d.ts +3 -3
  55. package/linter/rules/useless-loop.js +4 -4
  56. package/package.json +1 -1
  57. package/project/plugins/file-plugins/files/flowr-namespace-file.js +2 -2
  58. package/queries/catalog/call-context-query/identify-link-to-last-call-relation.js +3 -3
  59. package/queries/catalog/does-call-query/does-call-query-format.js +2 -2
  60. package/queries/catalog/inspect-exceptions-query/inspect-exception-query-format.js +5 -4
  61. package/queries/catalog/inspect-higher-order-query/inspect-higher-order-query-format.d.ts +1 -1
  62. package/queries/catalog/inspect-higher-order-query/inspect-higher-order-query-format.js +5 -4
  63. package/queries/catalog/inspect-recursion-query/inspect-recursion-query-format.js +4 -3
  64. package/queries/catalog/linter-query/linter-query-format.d.ts +1 -1
  65. package/queries/catalog/linter-query/linter-query-format.js +13 -9
  66. package/queries/query.d.ts +1 -1
  67. package/r-bridge/lang-4.x/ast/parser/main/normalize-meta.d.ts +1 -1
  68. package/r-bridge/lang-4.x/ast/parser/main/normalize-meta.js +2 -2
  69. package/r-bridge/lang-4.x/tree-sitter/tree-sitter-normalize.js +3 -3
  70. package/r-bridge/roxygen2/roxygen-parse.js +1 -1
  71. package/slicing/static/slice-call.js +1 -1
  72. package/statistics/features/supported/defined-functions/defined-functions.d.ts +1 -1
  73. package/statistics/features/supported/defined-functions/defined-functions.js +4 -4
  74. package/statistics/features/supported/used-functions/used-functions.js +3 -3
  75. package/statistics/features/supported/variables/variables.js +4 -4
  76. package/util/mermaid/dfg.d.ts +0 -5
  77. package/util/mermaid/dfg.js +6 -23
  78. package/util/range.d.ts +137 -54
  79. package/util/range.js +249 -88
  80. package/util/version.js +1 -1
package/README.md CHANGED
@@ -24,7 +24,7 @@ It offers a wide variety of features, for example:
24
24
 
25
25
  ```shell
26
26
  $ docker run -it --rm eagleoutice/flowr # or npm run flowr
27
- flowR repl using flowR v2.9.0, R grammar v14 (tree-sitter engine)
27
+ flowR repl using flowR v2.9.2, R grammar v14 (tree-sitter engine)
28
28
  R> :query @linter "read.csv(\"/root/x.txt\")"
29
29
  ```
30
30
 
@@ -47,18 +47,18 @@ It offers a wide variety of features, for example:
47
47
  ╰ Path `/root/x.txt` at 1.1-23
48
48
  ╰ Metadata: totalConsidered: 1, totalUnknown: 0, searchTimeMs: 0, processTimeMs: 0
49
49
  ╰ Unused Definitions (unused-definitions):
50
- ╰ Metadata: totalConsidered: 0, searchTimeMs: 0, processTimeMs: 0
50
+ ╰ Metadata: totalConsidered: 0, searchTimeMs: 0, processTimeMs: 1
51
51
  ╰ Naming Convention (naming-convention):
52
52
  ╰ Metadata: numMatches: 0, numBreak: 0, searchTimeMs: 0, processTimeMs: 0
53
53
  ╰ Network Functions (network-functions):
54
54
  ╰ Metadata: totalCalls: 0, totalFunctionDefinitions: 0, searchTimeMs: 0, processTimeMs: 0
55
55
  ╰ Dataframe Access Validation (dataframe-access-validation):
56
- ╰ Metadata: numOperations: 0, numAccesses: 0, totalAccessed: 0, searchTimeMs: 0, processTimeMs: 1
56
+ ╰ Metadata: numOperations: 0, numAccesses: 0, totalAccessed: 0, searchTimeMs: 0, processTimeMs: 0
57
57
  ╰ Dead Code (dead-code):
58
58
  ╰ Metadata: consideredNodes: 5, searchTimeMs: 0, processTimeMs: 0
59
59
  ╰ Useless Loops (useless-loop):
60
60
  ╰ Metadata: numOfUselessLoops: 0, searchTimeMs: 0, processTimeMs: 0
61
- All queries together required ≈2 ms (1ms accuracy, total 2 ms)
61
+ All queries together required ≈2 ms (1ms accuracy, total 3 ms)
62
62
  ```
63
63
 
64
64
 
@@ -80,9 +80,9 @@ It offers a wide variety of features, for example:
80
80
 
81
81
  _Results (prettified and summarized):_
82
82
 
83
- Query: **linter** (2 ms)\
83
+ Query: **linter** (3 ms)\
84
84
     ╰ **Deprecated Functions** (deprecated-functions):\
85
- &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;╰ _Metadata_: <code>totalCalls: 0, totalFunctionDefinitions: 0, searchTimeMs: 0, processTimeMs: 1</code>\
85
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;╰ _Metadata_: <code>totalCalls: 0, totalFunctionDefinitions: 0, searchTimeMs: 1, processTimeMs: 0</code>\
86
86
  &nbsp;&nbsp;&nbsp;╰ **File Path Validity** (file-path-validity):\
87
87
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;╰ certain:\
88
88
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;╰ Path `/root/x.txt` at 1.1-23\
@@ -100,16 +100,16 @@ It offers a wide variety of features, for example:
100
100
  &nbsp;&nbsp;&nbsp;╰ **Network Functions** (network-functions):\
101
101
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;╰ _Metadata_: <code>totalCalls: 0, totalFunctionDefinitions: 0, searchTimeMs: 0, processTimeMs: 0</code>\
102
102
  &nbsp;&nbsp;&nbsp;╰ **Dataframe Access Validation** (dataframe-access-validation):\
103
- &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;╰ _Metadata_: <code>numOperations: 0, numAccesses: 0, totalAccessed: 0, searchTimeMs: 0, processTimeMs: 0</code>\
103
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;╰ _Metadata_: <code>numOperations: 0, numAccesses: 0, totalAccessed: 0, searchTimeMs: 0, processTimeMs: 1</code>\
104
104
  &nbsp;&nbsp;&nbsp;╰ **Dead Code** (dead-code):\
105
105
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;╰ _Metadata_: <code>consideredNodes: 5, searchTimeMs: 0, processTimeMs: 0</code>\
106
106
  &nbsp;&nbsp;&nbsp;╰ **Useless Loops** (useless-loop):\
107
107
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;╰ _Metadata_: <code>numOfUselessLoops: 0, searchTimeMs: 0, processTimeMs: 0</code>\
108
- _All queries together required ≈2 ms (1ms accuracy, total 2 ms)_
108
+ _All queries together required ≈3 ms (1ms accuracy, total 3 ms)_
109
109
 
110
110
  <details> <summary style="color:gray">Show Detailed Results as Json</summary>
111
111
 
112
- The analysis required _2.2 ms_ (including parsing and normalization and the query) within the generation environment.
112
+ The analysis required _2.9 ms_ (including parsing and normalization and the query) within the generation environment.
113
113
 
114
114
  In general, the JSON contains the Ids of the nodes in question as they are present in the normalized AST or the dataflow graph of flowR.
115
115
  Please consult the [Interface](https://github.com/flowr-analysis/flowr/wiki/Interface) wiki page for more information on how to get those.
@@ -126,15 +126,15 @@ It offers a wide variety of features, for example:
126
126
  ".meta": {
127
127
  "totalCalls": 0,
128
128
  "totalFunctionDefinitions": 0,
129
- "searchTimeMs": 0,
130
- "processTimeMs": 1
129
+ "searchTimeMs": 1,
130
+ "processTimeMs": 0
131
131
  }
132
132
  },
133
133
  "file-path-validity": {
134
134
  "results": [
135
135
  {
136
136
  "involvedId": 3,
137
- "range": [
137
+ "loc": [
138
138
  1,
139
139
  1,
140
140
  1,
@@ -170,7 +170,7 @@ It offers a wide variety of features, for example:
170
170
  {
171
171
  "certainty": "certain",
172
172
  "filePath": "/root/x.txt",
173
- "range": [
173
+ "loc": [
174
174
  1,
175
175
  1,
176
176
  1,
@@ -218,7 +218,7 @@ It offers a wide variety of features, for example:
218
218
  "numAccesses": 0,
219
219
  "totalAccessed": 0,
220
220
  "searchTimeMs": 0,
221
- "processTimeMs": 0
221
+ "processTimeMs": 1
222
222
  }
223
223
  },
224
224
  "dead-code": {
@@ -239,11 +239,11 @@ It offers a wide variety of features, for example:
239
239
  }
240
240
  },
241
241
  ".meta": {
242
- "timing": 2
242
+ "timing": 3
243
243
  }
244
244
  },
245
245
  ".meta": {
246
- "timing": 2
246
+ "timing": 3
247
247
  }
248
248
  }
249
249
  ```
@@ -308,7 +308,7 @@ It offers a wide variety of features, for example:
308
308
 
309
309
  ```shell
310
310
  $ docker run -it --rm eagleoutice/flowr # or npm run flowr
311
- flowR repl using flowR v2.9.0, R grammar v14 (tree-sitter engine)
311
+ flowR repl using flowR v2.9.2, R grammar v14 (tree-sitter engine)
312
312
  R> :query @static-slice (11@sum) file://test/testfiles/example.R
313
313
  ```
314
314
 
@@ -322,7 +322,7 @@ It offers a wide variety of features, for example:
322
322
  N <- 10
323
323
  for(i in 1:(N-1)) sum <- sum + i + w
324
324
  sum
325
- All queries together required ≈3 ms (1ms accuracy, total 4 ms)
325
+ All queries together required ≈3 ms (1ms accuracy, total 3 ms)
326
326
  ```
327
327
 
328
328
 
@@ -356,7 +356,7 @@ It offers a wide variety of features, for example:
356
356
 
357
357
 
358
358
  * 🚀 **fast call-graph, data-, and control-flow graphs**\
359
- Within just [<i><span title="This measurement is automatically fetched from the latest benchmark!">117.5 ms</span></i> (as of Feb 2, 2026)](https://flowr-analysis.github.io/flowr/wiki/stats/benchmark),
359
+ Within just [<i><span title="This measurement is automatically fetched from the latest benchmark!">117 ms</span></i> (as of Feb 3, 2026)](https://flowr-analysis.github.io/flowr/wiki/stats/benchmark),
360
360
  _flowR_ can analyze the data- and control-flow of the average real-world R script. See the [benchmarks](https://flowr-analysis.github.io/flowr/wiki/stats/benchmark) for more information,
361
361
  and consult the [wiki pages](https://github.com/flowr-analysis/flowr/wiki/wiki/dataflow-graph) for more details on the dataflow graphs as well as call graphs.
362
362
 
@@ -392,7 +392,7 @@ It offers a wide variety of features, for example:
392
392
 
393
393
  ```shell
394
394
  $ docker run -it --rm eagleoutice/flowr # or npm run flowr
395
- flowR repl using flowR v2.9.0, R grammar v14 (tree-sitter engine)
395
+ flowR repl using flowR v2.9.2, R grammar v14 (tree-sitter engine)
396
396
  R> :dataflow* test/testfiles/example.R
397
397
  ```
398
398
 
@@ -697,7 +697,7 @@ It offers a wide variety of features, for example:
697
697
  ```
698
698
 
699
699
 
700
- (The analysis required _1.7 ms_ (including parse and normalize, using the [tree-sitter](https://github.com/flowr-analysis/flowr/wiki/Engines) engine) within the generation environment.)
700
+ (The analysis required _2.0 ms_ (including parse and normalize, using the [tree-sitter](https://github.com/flowr-analysis/flowr/wiki/Engines) engine) within the generation environment.)
701
701
 
702
702
 
703
703
 
@@ -9,11 +9,11 @@ function grayOut() {
9
9
  }
10
10
  function mergeJointRangesInSorted(loc) {
11
11
  return loc.reduce((acc, curr) => {
12
- if ((0, range_1.rangesOverlap)(acc[acc.length - 1].location, curr.location)) {
12
+ if (range_1.SourceRange.overlap(acc[acc.length - 1].location, curr.location)) {
13
13
  return [
14
14
  ...acc.slice(0, -1), {
15
15
  selected: curr.selected || acc[acc.length - 1].selected,
16
- location: (0, range_1.mergeRanges)([acc[acc.length - 1].location, curr.location])
16
+ location: range_1.SourceRange.merge([acc[acc.length - 1].location, curr.location])
17
17
  }
18
18
  ];
19
19
  }
@@ -37,7 +37,7 @@ function sliceDiffAnsi(slice, normalized, criteriaIds, originalCode) {
37
37
  return `${grayOut()}${originalCode}${ansi_1.ansiFormatter.reset()}`;
38
38
  }
39
39
  // we sort all locations from back to front so that replacements do not screw up the indices
40
- importantLocations.sort((a, b) => -(0, range_1.rangeCompare)(a.location, b.location));
40
+ importantLocations.sort((a, b) => -range_1.SourceRange.compare(a.location, b.location));
41
41
  // we need to merge all ranges that overlap, otherwise even reversed traversal can still crew us up
42
42
  importantLocations = mergeJointRangesInSorted(importantLocations);
43
43
  const lines = originalCode.split('\n');
@@ -83,7 +83,16 @@ export interface DefaultBuiltInProcessorConfiguration extends ForceArguments {
83
83
  */
84
84
  readonly useAsProcessor?: BuiltInProcName;
85
85
  }
86
- export type BuiltInEvalHandler = (resolve: VariableResolve, a: RNodeWithParent, ctx: ReadOnlyFlowrAnalyzerContext, env?: REnvironmentInformation, graph?: DataflowGraph, map?: AstIdMap) => Value;
86
+ export interface BuiltInEvalHandlerArgs {
87
+ resolve: VariableResolve;
88
+ node: RNodeWithParent;
89
+ ctx: ReadOnlyFlowrAnalyzerContext;
90
+ environment?: REnvironmentInformation;
91
+ graph?: DataflowGraph;
92
+ idMap?: AstIdMap;
93
+ blocked?: Set<NodeId>;
94
+ }
95
+ export type BuiltInEvalHandler = (args: BuiltInEvalHandlerArgs) => Value;
87
96
  declare function defaultBuiltInProcessor<OtherInfo>(name: RSymbol<OtherInfo & ParentInformation>, args: readonly RFunctionArgument<OtherInfo & ParentInformation>[], rootId: NodeId, data: DataflowProcessorInformation<OtherInfo & ParentInformation>, { returnsNthArgument, useAsProcessor, forceArgs, readAllArguments, cfg, hasUnknownSideEffects, treatAsFnCall }: DefaultBuiltInProcessorConfiguration): DataflowInformation;
88
97
  /**
89
98
  * This contains all names of built-in function handlers and origins
@@ -426,6 +426,7 @@ export declare const DefaultBuiltinConfig: [{
426
426
  readonly idx: 2;
427
427
  readonly name: "definition";
428
428
  };
429
+ readonly modesForFn: ["s4"];
429
430
  };
430
431
  readonly assumePrimitive: true;
431
432
  }, {
@@ -258,7 +258,7 @@ exports.DefaultBuiltinConfig = [
258
258
  { type: 'function', names: ['<-', '='], processor: built_in_1.BuiltInProcName.Assignment, config: { canBeReplacement: true }, assumePrimitive: true },
259
259
  { type: 'function', names: [':='], processor: built_in_1.BuiltInProcName.Assignment, config: {}, assumePrimitive: true },
260
260
  { type: 'function', names: ['assign', 'setValidity'], processor: built_in_1.BuiltInProcName.Assignment, config: { targetVariable: true, mayHaveMoreArgs: true }, assumePrimitive: true },
261
- { type: 'function', names: ['setMethod'], processor: built_in_1.BuiltInProcName.AssignmentLike, config: { targetVariable: true, canBeReplacement: false, target: { idx: 0, name: 'f' }, source: { idx: 2, name: 'definition' } }, assumePrimitive: true },
261
+ { type: 'function', names: ['setMethod'], processor: built_in_1.BuiltInProcName.AssignmentLike, config: { targetVariable: true, canBeReplacement: false, target: { idx: 0, name: 'f' }, source: { idx: 2, name: 'definition' }, modesForFn: ['s4'] }, assumePrimitive: true },
262
262
  { type: 'function', names: ['delayedAssign'], processor: built_in_1.BuiltInProcName.Assignment, config: { quoteSource: true, targetVariable: true }, assumePrimitive: true },
263
263
  { type: 'function', names: ['<<-'], processor: built_in_1.BuiltInProcName.Assignment, config: { superAssignment: true, canBeReplacement: true }, assumePrimitive: true },
264
264
  { type: 'function', names: ['->'], processor: built_in_1.BuiltInProcName.Assignment, config: { swapSourceAndTarget: true, canBeReplacement: true }, assumePrimitive: true },
@@ -2,7 +2,7 @@ import { VariableResolve } from '../../../config';
2
2
  import type { AstIdMap, RNodeWithParent } from '../../../r-bridge/lang-4.x/ast/model/processing/decorate';
3
3
  import { type NodeId } from '../../../r-bridge/lang-4.x/ast/model/processing/node-id';
4
4
  import { type REnvironmentInformation } from '../../environments/environment';
5
- import { type Identifier } from '../../environments/identifier';
5
+ import { Identifier } from '../../environments/identifier';
6
6
  import type { DataflowGraph } from '../../graph/graph';
7
7
  import { type Lift, type Value, type ValueSet } from '../values/r-value';
8
8
  import type { ReadOnlyFlowrAnalyzerContext } from '../../../project/context/flowr-analyzer-context';
@@ -20,6 +20,8 @@ export interface ResolveInfo {
20
20
  resolve?: VariableResolve;
21
21
  /** Context used for resolving */
22
22
  ctx: ReadOnlyFlowrAnalyzerContext;
23
+ /** If set, the ids that should not be considered during resolution (=&gt; top) */
24
+ blocked?: Set<NodeId>;
23
25
  }
24
26
  /**
25
27
  * Gets the definitions / aliases of a node
@@ -54,22 +56,20 @@ export declare function getAliases(sourceIds: readonly NodeId[], dataflow: Dataf
54
56
  * @param full - Whether to track aliases on resolve
55
57
  * @param resolve - Variable resolve mode
56
58
  * @param ctx - Context used for clean environment
59
+ * @param blocked - If set, the ids that should not be considered during resolution (=&gt;top)
57
60
  */
58
- export declare function resolveIdToValue(id: NodeId | RNodeWithParent | undefined, { environment, graph, idMap, full, resolve, ctx }: ResolveInfo): ResolveResult;
61
+ export declare function resolveIdToValue(id: NodeId | RNodeWithParent | undefined, { environment, graph, idMap, full, resolve, ctx, blocked }: ResolveInfo): ResolveResult;
59
62
  /**
60
63
  * Please use {@link resolveIdToValue}
61
64
  *
62
65
  * Uses the aliases that were tracked in the environments (by the
63
66
  * {@link getAliases} function) to resolve a node to a value.
64
- * @param resolve - Variable resolve mode
65
67
  * @param identifier - Identifier to resolve
66
- * @param use - Environment to use
67
- * @param ctx - analysis context
68
- * @param graph - dataflow graph
69
- * @param idMap - id map of Dataflow graph
68
+ * @param environment - Environment to use
69
+ * @param r - Resolve information (env, ctx, ...)
70
70
  * @returns Value of Identifier or Top
71
71
  */
72
- export declare function trackAliasInEnvironments(resolve: VariableResolve, identifier: Identifier | undefined, use: REnvironmentInformation, ctx: ReadOnlyFlowrAnalyzerContext, graph?: DataflowGraph, idMap?: AstIdMap): ResolveResult;
72
+ export declare function trackAliasInEnvironments(identifier: Identifier | undefined, environment: REnvironmentInformation, { blocked, idMap, resolve, ctx, graph }: Omit<ResolveInfo, 'environment'>): ResolveResult;
73
73
  /**
74
74
  * Please use {@link resolveIdToValue}
75
75
  *
@@ -117,39 +117,44 @@ function getAliases(sourceIds, dataflow, environment) {
117
117
  * @param full - Whether to track aliases on resolve
118
118
  * @param resolve - Variable resolve mode
119
119
  * @param ctx - Context used for clean environment
120
+ * @param blocked - If set, the ids that should not be considered during resolution (=&gt;top)
120
121
  */
121
- function resolveIdToValue(id, { environment, graph, idMap, full = true, resolve, ctx }) {
122
+ function resolveIdToValue(id, { environment, graph, idMap, full = true, resolve, ctx, blocked }) {
122
123
  const variableResolve = resolve ?? ctx.config.solver.variables;
124
+ blocked ??= new Set();
123
125
  if (id === undefined) {
124
126
  return r_value_1.Top;
125
127
  }
126
128
  idMap ??= graph?.idMap;
127
129
  const node = typeof id === 'object' ? id : idMap?.get(id);
128
- if (node === undefined) {
130
+ if (node === undefined || blocked.has(node.info.id)) {
129
131
  return r_value_1.Top;
130
132
  }
133
+ blocked.add(node.info.id);
131
134
  switch (node.type) {
132
135
  case type_1.RType.Argument:
133
136
  if (node.value) {
134
- return resolveIdToValue(node.value.info.id, { environment, graph, idMap, full, resolve: variableResolve, ctx });
137
+ return resolveIdToValue(node.value.info.id, { environment, graph, idMap, full, resolve: variableResolve, ctx, blocked });
135
138
  }
136
139
  // eslint-disable-next-line no-fallthrough
137
140
  case type_1.RType.Symbol:
138
- if (environment) {
139
- return full ? trackAliasInEnvironments(variableResolve, node.lexeme, environment, ctx, graph, idMap) : r_value_1.Top;
140
- }
141
- else if (graph && resolve === config_1.VariableResolve.Alias) {
142
- return full ? trackAliasesInGraph(node.info.id, graph, ctx, idMap) : r_value_1.Top;
143
- }
144
- else {
145
- return r_value_1.Top;
141
+ if (full) {
142
+ if (environment) {
143
+ return trackAliasInEnvironments(identifier_1.Identifier.toString(node.content), environment, { idMap, resolve: variableResolve, ctx, graph, blocked });
144
+ }
145
+ else if (graph && resolve === config_1.VariableResolve.Alias) {
146
+ return trackAliasesInGraph(node.info.id, graph, ctx, idMap);
147
+ }
146
148
  }
149
+ return r_value_1.Top;
147
150
  case type_1.RType.FunctionDefinition:
148
151
  return (0, set_constants_1.setFrom)({ type: 'function-definition' });
149
152
  case type_1.RType.FunctionCall:
150
153
  case type_1.RType.BinaryOp:
151
154
  case type_1.RType.UnaryOp:
152
- return (0, set_constants_1.setFrom)((0, resolve_1.resolveNode)(variableResolve, node, ctx, environment, graph, idMap));
155
+ return (0, set_constants_1.setFrom)((0, resolve_1.resolveNode)({
156
+ resolve: variableResolve, node, ctx, environment, graph, idMap, blocked
157
+ }));
153
158
  case type_1.RType.String:
154
159
  case type_1.RType.Number:
155
160
  case type_1.RType.Logical:
@@ -163,19 +168,16 @@ function resolveIdToValue(id, { environment, graph, idMap, full = true, resolve,
163
168
  *
164
169
  * Uses the aliases that were tracked in the environments (by the
165
170
  * {@link getAliases} function) to resolve a node to a value.
166
- * @param resolve - Variable resolve mode
167
171
  * @param identifier - Identifier to resolve
168
- * @param use - Environment to use
169
- * @param ctx - analysis context
170
- * @param graph - dataflow graph
171
- * @param idMap - id map of Dataflow graph
172
+ * @param environment - Environment to use
173
+ * @param r - Resolve information (env, ctx, ...)
172
174
  * @returns Value of Identifier or Top
173
175
  */
174
- function trackAliasInEnvironments(resolve, identifier, use, ctx, graph, idMap) {
176
+ function trackAliasInEnvironments(identifier, environment, { blocked, idMap, resolve = config_1.VariableResolve.Alias, ctx, graph }) {
175
177
  if (identifier === undefined) {
176
178
  return r_value_1.Top;
177
179
  }
178
- const defs = (0, resolve_by_name_1.resolveByNameAnyType)(identifier, use);
180
+ const defs = (0, resolve_by_name_1.resolveByNameAnyType)(identifier, environment);
179
181
  if (defs === undefined) {
180
182
  return r_value_1.Top;
181
183
  }
@@ -195,7 +197,7 @@ function trackAliasInEnvironments(resolve, identifier, use, ctx, graph, idMap) {
195
197
  for (const alias of def.value) {
196
198
  const definitionOfAlias = idMap?.get(alias);
197
199
  if (definitionOfAlias !== undefined) {
198
- const value = (0, resolve_1.resolveNode)(resolve, definitionOfAlias, ctx, use, graph, idMap);
200
+ const value = (0, resolve_1.resolveNode)({ resolve, node: definitionOfAlias, ctx, environment, graph, idMap, blocked });
199
201
  if ((0, r_value_1.isTop)(value)) {
200
202
  return r_value_1.Top;
201
203
  }
@@ -252,7 +254,7 @@ function isNestedInLoop(node, ast) {
252
254
  if (parentNode === undefined) {
253
255
  return false;
254
256
  }
255
- if (parentNode.type === type_1.RType.WhileLoop || parentNode.type === type_1.RType.RepeatLoop) {
257
+ if (parentNode.type === type_1.RType.WhileLoop || parentNode.type === type_1.RType.RepeatLoop || parentNode.type === type_1.RType.ForLoop) {
256
258
  return true;
257
259
  }
258
260
  return isNestedInLoop(parentNode, ast);
@@ -273,7 +275,7 @@ function trackAliasesInGraph(id, graph, ctx, idMap) {
273
275
  }
274
276
  idMap ??= graph.idMap;
275
277
  (0, assert_1.guard)(idMap !== undefined, 'The ID map is required to get the lineage of a node');
276
- const queue = new visiting_queue_1.VisitingQueue(25);
278
+ const queue = new visiting_queue_1.VisitingQueue(10);
277
279
  const clean = ctx.env.makeCleanEnv();
278
280
  const cleanFingerprint = ctx.env.getCleanEnvFingerprint();
279
281
  queue.add(id, clean, cleanFingerprint, false);
@@ -281,11 +283,10 @@ function trackAliasesInGraph(id, graph, ctx, idMap) {
281
283
  const resultIds = [];
282
284
  while (queue.nonEmpty()) {
283
285
  const { id, baseEnvironment } = queue.next();
284
- const res = graph.get(id);
285
- if (!res) {
286
+ const vertex = graph.getVertex(id);
287
+ if (!vertex) {
286
288
  continue;
287
289
  }
288
- const [vertex, outgoingEdges] = res;
289
290
  const cds = vertex.cds;
290
291
  for (const cd of cds ?? []) {
291
292
  const target = graph.idMap?.get(cd.id);
@@ -303,25 +304,23 @@ function trackAliasesInGraph(id, graph, ctx, idMap) {
303
304
  if (forceTop) {
304
305
  break;
305
306
  }
306
- if (vertex.tag === vertex_1.VertexType.Value) {
307
- resultIds.push(id);
308
- continue;
309
- }
310
- else if (vertex.tag === vertex_1.VertexType.FunctionDefinition) {
307
+ const t = vertex.tag;
308
+ if (t === vertex_1.VertexType.Value || t === vertex_1.VertexType.FunctionDefinition) {
311
309
  resultIds.push(id);
312
310
  continue;
313
311
  }
314
- const isFn = vertex.tag === vertex_1.VertexType.FunctionCall;
312
+ const isFn = t === vertex_1.VertexType.FunctionCall;
313
+ const outgoingEdges = graph.outgoingEdges(id) ?? [];
315
314
  // travel all read and defined-by edges
316
- for (const [targetId, edge] of outgoingEdges) {
315
+ for (const [targetId, { types }] of outgoingEdges) {
317
316
  if (isFn) {
318
- if (edge.types === edge_1.EdgeType.Returns || edge.types === edge_1.EdgeType.DefinedByOnCall || edge.types === edge_1.EdgeType.DefinedBy) {
317
+ if (types === edge_1.EdgeType.Returns || types === edge_1.EdgeType.DefinedByOnCall || types === edge_1.EdgeType.DefinedBy) {
319
318
  queue.add(targetId, baseEnvironment, cleanFingerprint, false);
320
319
  }
321
320
  continue;
322
321
  }
323
322
  // currently, they have to be exact!
324
- if (edge.types === edge_1.EdgeType.Reads || edge.types === edge_1.EdgeType.DefinedBy || edge.types === edge_1.EdgeType.DefinedByOnCall) {
323
+ if (types === edge_1.EdgeType.Reads || types === edge_1.EdgeType.DefinedBy || types === edge_1.EdgeType.DefinedByOnCall) {
325
324
  queue.add(targetId, baseEnvironment, cleanFingerprint, false);
326
325
  }
327
326
  }
@@ -26,7 +26,7 @@ function getArgumentStringValue(variableResolve, graph, vertex, argumentIndex, a
26
26
  }
27
27
  if (argumentIndex === 'unnamed') {
28
28
  // return all unnamed arguments
29
- const references = vertex.args.filter(arg => arg !== r_function_call_1.EmptyArgument && !arg.name).map(graph_1.getReferenceOfArgument).filter(assert_1.isNotUndefined);
29
+ const references = vertex.args.filter(arg => arg !== r_function_call_1.EmptyArgument && !arg.name).map(graph_1.FunctionArgument.getReference).filter(assert_1.isNotUndefined);
30
30
  const map = new Map();
31
31
  for (const ref of references) {
32
32
  let valueNode = graph.idMap?.get(ref);
@@ -42,7 +42,7 @@ function getArgumentStringValue(variableResolve, graph, vertex, argumentIndex, a
42
42
  return map;
43
43
  }
44
44
  if (argumentIndex < vertex.args.length) {
45
- const arg = (0, graph_1.getReferenceOfArgument)(vertex.args[argumentIndex]);
45
+ const arg = graph_1.FunctionArgument.getReference(vertex.args[argumentIndex]);
46
46
  if (!arg) {
47
47
  return undefined;
48
48
  }
@@ -1,81 +1,47 @@
1
- import type { AstIdMap, RNodeWithParent } from '../../../r-bridge/lang-4.x/ast/model/processing/decorate';
2
- import type { REnvironmentInformation } from '../../environments/environment';
3
- import type { DataflowGraph } from '../../graph/graph';
1
+ import type { BuiltInEvalHandlerArgs } from '../../environments/built-in';
4
2
  import { type Lift, Top, type Value, type ValueNumber, type ValueVector } from '../values/r-value';
5
- import type { VariableResolve } from '../../../config';
6
- import type { ReadOnlyFlowrAnalyzerContext } from '../../../project/context/flowr-analyzer-context';
7
3
  /**
8
4
  * Helper function used by {@link resolveIdToValue}, please use that instead, if
9
5
  * you want to resolve the value of an identifier / node
10
6
  *
11
7
  * This function converts an RNode to its Value, but also recursively resolves
12
- * aliases and vectors (in case of a vector).
13
- * @param a - Ast node to resolve
14
- * @param resolve - Variable resolve mode
15
- * @param ctx - Analyzer context
16
- * @param env - Environment to use
17
- * @param graph - Dataflow Graph to use
18
- * @param map - Idmap of Dataflow Graph
8
+ * aliases and vectors (in case of node vector).
19
9
  * @returns resolved value or top/bottom
20
10
  */
21
- export declare function resolveNode(resolve: VariableResolve, a: RNodeWithParent, ctx: ReadOnlyFlowrAnalyzerContext, env?: REnvironmentInformation, graph?: DataflowGraph, map?: AstIdMap): Value;
11
+ export declare function resolveNode({ resolve, node, ctx, blocked, environment, graph, idMap }: BuiltInEvalHandlerArgs): Value;
22
12
  /**
23
13
  * Helper function used by {@link resolveIdToValue}, please use that instead, if
24
14
  * you want to resolve the value of an identifier / node
25
15
  *
26
16
  * This function resolves a vector function call `c` to a {@link ValueVector}
27
17
  * by recursively resolving the values of the arguments by calling {@link resolveIdToValue}
28
- * @param resolve - Variable resolve mode
29
- * @param node - Node of the vector function to resolve
30
- * @param environment - Environment to use
31
- * @param ctx - Analyzer context
32
- * @param graph - Dataflow graph
33
- * @param idMap - ID map of the dataflow graph
34
18
  * @returns ValueVector or Top
35
19
  */
36
- export declare function resolveAsVector(resolve: VariableResolve, node: RNodeWithParent, ctx: ReadOnlyFlowrAnalyzerContext, environment?: REnvironmentInformation, graph?: DataflowGraph, idMap?: AstIdMap): ValueVector<Lift<Value[]>> | typeof Top;
20
+ export declare function resolveAsVector({ resolve, environment, node, graph, idMap, ctx, blocked }: BuiltInEvalHandlerArgs): ValueVector | typeof Top;
37
21
  /**
38
22
  * Helper function used by {@link resolveIdToValue}, please use that instead, if
39
23
  * you want to resolve the value of an identifier / node
40
24
  *
41
25
  * This function resolves a binary sequence operator `:` to a {@link ValueVector} of {@link ValueNumber}s
42
26
  * by recursively resolving the values of the arguments by calling {@link resolveIdToValue}
43
- * @param resolve - Variable resolve mode
44
- * @param operator - Node of the sequence operator to resolve
45
- * @param graph - Dataflow graph
46
- * @param ctx - Analyzer context
47
- * @param idMap - Id map of the dataflow graph
48
- * @param environment - Environment to use
49
27
  * @returns ValueVector of ValueNumbers or Top
50
28
  */
51
- export declare function resolveAsSeq(resolve: VariableResolve, operator: RNodeWithParent, ctx: ReadOnlyFlowrAnalyzerContext, environment?: REnvironmentInformation, graph?: DataflowGraph, idMap?: AstIdMap): ValueVector<Lift<ValueNumber[]>> | typeof Top;
29
+ export declare function resolveAsSeq({ node: operator, environment, resolve, ctx, graph, idMap, blocked }: BuiltInEvalHandlerArgs): ValueVector<Lift<ValueNumber[]>> | typeof Top;
52
30
  /**
53
31
  * Helper function used by {@link resolveIdToValue}, please use that instead, if
54
32
  * you want to resolve the value of an identifier / node
55
33
  *
56
34
  * This function resolves a unary plus operator `+` to a {@link ValueNumber} or {@link ValueVector} of ValueNumbers
57
35
  * by recursively resolving the values of the arguments by calling {@link resolveIdToValue}
58
- * @param resolve - Variable resolve mode
59
- * @param operator - Node of the plus operator to resolve
60
- * @param graph - Dataflow graph
61
- * @param ctx - Analyzer context
62
- * @param idMap - Id map of the dataflow graph
63
- * @param environment - Environment to use
64
36
  * @returns ValueNumber, ValueVector of ValueNumbers, or Top
65
37
  */
66
- export declare function resolveAsPlus(resolve: VariableResolve, operator: RNodeWithParent, ctx: ReadOnlyFlowrAnalyzerContext, environment?: REnvironmentInformation, graph?: DataflowGraph, idMap?: AstIdMap): ValueNumber | ValueVector<Lift<ValueNumber[]>> | typeof Top;
38
+ export declare function resolveAsPlus({ node: operator, environment, resolve, ctx, graph, idMap, blocked }: BuiltInEvalHandlerArgs): ValueNumber | ValueVector<Lift<ValueNumber[]>> | typeof Top;
67
39
  /**
68
40
  * Helper function used by {@link resolveIdToValue}, please use that instead, if
69
41
  * you want to resolve the value of an identifier / node
70
42
  *
71
43
  * This function resolves a unary minus operator `-` to a {@link ValueNumber} or {@link ValueVector} of ValueNumbers
72
44
  * by recursively resolving the values of the arguments by calling {@link resolveIdToValue}
73
- * @param resolve - Variable resolve mode
74
- * @param operator - Node of the minus operator to resolve
75
- * @param graph - Dataflow graph
76
- * @param ctx - Analyzer context
77
- * @param idMap - Id map of the dataflow graph
78
- * @param environment - Environment to use
79
45
  * @returns ValueNumber, ValueVector of ValueNumbers, or Top
80
46
  */
81
- export declare function resolveAsMinus(resolve: VariableResolve, operator: RNodeWithParent, ctx: ReadOnlyFlowrAnalyzerContext, environment?: REnvironmentInformation, graph?: DataflowGraph, idMap?: AstIdMap): ValueNumber | ValueVector<Lift<ValueNumber[]>> | typeof Top;
47
+ export declare function resolveAsMinus({ node: operator, environment, resolve, ctx, graph, idMap, blocked }: BuiltInEvalHandlerArgs): ValueNumber | ValueVector<Lift<ValueNumber[]>> | typeof Top;