@eagleoutice/flowr 2.2.13 → 2.2.15

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 (145) hide show
  1. package/README.md +4 -4
  2. package/cli/repl/commands/repl-cfg.d.ts +2 -2
  3. package/cli/repl/commands/repl-cfg.js +4 -4
  4. package/cli/repl/commands/repl-commands.js +3 -3
  5. package/cli/repl/commands/repl-execute.js +2 -1
  6. package/cli/repl/server/connection.js +1 -1
  7. package/cli/script-core/statistics-helper-core.js +1 -1
  8. package/config.js +1 -1
  9. package/control-flow/basic-cfg-guided-visitor.d.ts +3 -3
  10. package/control-flow/cfg-dead-code.d.ts +4 -0
  11. package/control-flow/cfg-dead-code.js +81 -0
  12. package/control-flow/cfg-simplification.d.ts +17 -6
  13. package/control-flow/cfg-simplification.js +23 -19
  14. package/control-flow/control-flow-graph.d.ts +2 -1
  15. package/control-flow/control-flow-graph.js +1 -0
  16. package/control-flow/dfg-cfg-guided-visitor.d.ts +4 -4
  17. package/control-flow/dfg-cfg-guided-visitor.js +1 -1
  18. package/control-flow/extract-cfg.d.ts +2 -2
  19. package/control-flow/extract-cfg.js +70 -67
  20. package/control-flow/semantic-cfg-guided-visitor.d.ts +17 -8
  21. package/control-flow/semantic-cfg-guided-visitor.js +50 -17
  22. package/control-flow/simple-visitor.d.ts +4 -0
  23. package/control-flow/simple-visitor.js +14 -0
  24. package/control-flow/syntax-cfg-guided-visitor.d.ts +2 -2
  25. package/dataflow/environments/built-in-config.d.ts +1 -0
  26. package/dataflow/environments/built-in.d.ts +10 -1
  27. package/dataflow/environments/built-in.js +9 -3
  28. package/dataflow/environments/default-builtin-config.js +1 -1
  29. package/dataflow/environments/resolve-by-name.d.ts +0 -36
  30. package/dataflow/environments/resolve-by-name.js +0 -240
  31. package/dataflow/eval/resolve/alias-tracking.d.ts +87 -0
  32. package/dataflow/eval/resolve/alias-tracking.js +349 -0
  33. package/dataflow/eval/resolve/resolve.d.ts +34 -0
  34. package/dataflow/eval/resolve/resolve.js +93 -0
  35. package/dataflow/eval/values/general.d.ts +27 -0
  36. package/dataflow/eval/values/general.js +73 -0
  37. package/dataflow/eval/values/intervals/interval-constants.d.ts +4 -0
  38. package/dataflow/eval/values/intervals/interval-constants.js +27 -0
  39. package/dataflow/eval/values/logical/logical-constants.d.ts +7 -0
  40. package/dataflow/eval/values/logical/logical-constants.js +31 -0
  41. package/dataflow/eval/values/r-value.d.ts +58 -0
  42. package/dataflow/eval/values/r-value.js +90 -0
  43. package/dataflow/eval/values/scalar/scalar-consatnts.d.ts +15 -0
  44. package/dataflow/eval/values/scalar/scalar-consatnts.js +35 -0
  45. package/dataflow/eval/values/sets/set-constants.d.ts +7 -0
  46. package/dataflow/eval/values/sets/set-constants.js +34 -0
  47. package/dataflow/eval/values/string/string-constants.d.ts +8 -0
  48. package/dataflow/eval/values/string/string-constants.js +40 -0
  49. package/dataflow/eval/values/vectors/vector-constants.d.ts +14 -0
  50. package/dataflow/eval/values/vectors/vector-constants.js +35 -0
  51. package/dataflow/graph/unknown-replacement.d.ts +11 -0
  52. package/dataflow/graph/unknown-replacement.js +12 -0
  53. package/dataflow/graph/unknown-side-effect.d.ts +7 -0
  54. package/dataflow/graph/unknown-side-effect.js +13 -0
  55. package/dataflow/internal/process/functions/call/built-in/built-in-apply.js +8 -5
  56. package/dataflow/internal/process/functions/call/built-in/built-in-assignment.js +4 -2
  57. package/dataflow/internal/process/functions/call/built-in/built-in-eval.js +12 -9
  58. package/dataflow/internal/process/functions/call/built-in/built-in-if-then-else.js +5 -4
  59. package/dataflow/internal/process/functions/call/built-in/built-in-replacement.js +9 -2
  60. package/dataflow/internal/process/functions/call/built-in/built-in-source.js +12 -15
  61. package/dataflow/internal/process/functions/call/built-in/built-in-while-loop.js +23 -0
  62. package/dataflow/internal/process/functions/call/known-call-handling.js +2 -1
  63. package/documentation/doc-util/doc-cfg.d.ts +1 -1
  64. package/documentation/doc-util/doc-cfg.js +3 -3
  65. package/documentation/doc-util/doc-query.d.ts +6 -3
  66. package/documentation/doc-util/doc-query.js +3 -1
  67. package/documentation/print-cfg-wiki.js +31 -31
  68. package/documentation/print-dataflow-graph-wiki.js +4 -3
  69. package/documentation/print-engines-wiki.js +1 -1
  70. package/documentation/print-linter-wiki.d.ts +1 -0
  71. package/documentation/print-linter-wiki.js +76 -0
  72. package/documentation/print-query-wiki.js +80 -0
  73. package/linter/linter-executor.d.ts +9 -0
  74. package/linter/linter-executor.js +26 -0
  75. package/linter/linter-format.d.ts +65 -0
  76. package/linter/linter-format.js +9 -0
  77. package/linter/linter-rules.d.ts +42 -0
  78. package/linter/linter-rules.js +14 -0
  79. package/linter/rules/1-deprecated-functions.d.ts +34 -0
  80. package/linter/rules/1-deprecated-functions.js +54 -0
  81. package/linter/rules/2-file-path-validity.d.ts +48 -0
  82. package/linter/rules/2-file-path-validity.js +93 -0
  83. package/package.json +2 -1
  84. package/queries/catalog/call-context-query/call-context-query-executor.js +1 -1
  85. package/queries/catalog/call-context-query/call-context-query-format.d.ts +2 -2
  86. package/queries/catalog/call-context-query/call-context-query-format.js +5 -1
  87. package/queries/catalog/cluster-query/cluster-query-format.d.ts +2 -0
  88. package/queries/catalog/cluster-query/cluster-query-format.js +5 -1
  89. package/queries/catalog/config-query/config-query-format.d.ts +1 -0
  90. package/queries/catalog/config-query/config-query-format.js +2 -1
  91. package/queries/catalog/control-flow-query/control-flow-query-executor.d.ts +3 -0
  92. package/queries/catalog/control-flow-query/control-flow-query-executor.js +20 -0
  93. package/queries/catalog/control-flow-query/control-flow-query-format.d.ts +81 -0
  94. package/queries/catalog/control-flow-query/control-flow-query-format.js +34 -0
  95. package/queries/catalog/dataflow-lens-query/dataflow-lens-query-format.d.ts +1 -0
  96. package/queries/catalog/dataflow-lens-query/dataflow-lens-query-format.js +2 -1
  97. package/queries/catalog/dataflow-query/dataflow-query-format.d.ts +2 -0
  98. package/queries/catalog/dataflow-query/dataflow-query-format.js +9 -1
  99. package/queries/catalog/dependencies-query/dependencies-query-executor.js +33 -32
  100. package/queries/catalog/dependencies-query/dependencies-query-format.d.ts +1 -0
  101. package/queries/catalog/dependencies-query/dependencies-query-format.js +10 -1
  102. package/queries/catalog/happens-before-query/happens-before-query-format.d.ts +1 -0
  103. package/queries/catalog/happens-before-query/happens-before-query-format.js +2 -1
  104. package/queries/catalog/id-map-query/id-map-query-format.d.ts +1 -0
  105. package/queries/catalog/id-map-query/id-map-query-format.js +2 -1
  106. package/queries/catalog/lineage-query/lineage-query-format.d.ts +1 -0
  107. package/queries/catalog/lineage-query/lineage-query-format.js +5 -1
  108. package/queries/catalog/linter-query/linter-query-executor.d.ts +3 -0
  109. package/queries/catalog/linter-query/linter-query-executor.js +28 -0
  110. package/queries/catalog/linter-query/linter-query-format.d.ts +80 -0
  111. package/queries/catalog/linter-query/linter-query-format.js +44 -0
  112. package/queries/catalog/location-map-query/location-map-query-format.d.ts +1 -0
  113. package/queries/catalog/location-map-query/location-map-query-format.js +2 -1
  114. package/queries/catalog/normalized-ast-query/normalized-ast-query-format.d.ts +1 -0
  115. package/queries/catalog/normalized-ast-query/normalized-ast-query-format.js +2 -1
  116. package/queries/catalog/origin-query/origin-query-format.d.ts +2 -0
  117. package/queries/catalog/origin-query/origin-query-format.js +5 -1
  118. package/queries/catalog/project-query/project-query-executor.js +1 -1
  119. package/queries/catalog/project-query/project-query-format.d.ts +1 -0
  120. package/queries/catalog/project-query/project-query-format.js +2 -1
  121. package/queries/catalog/resolve-value-query/resolve-value-query-executor.js +3 -3
  122. package/queries/catalog/resolve-value-query/resolve-value-query-format.d.ts +3 -1
  123. package/queries/catalog/resolve-value-query/resolve-value-query-format.js +4 -23
  124. package/queries/catalog/search-query/search-query-format.d.ts +1 -0
  125. package/queries/catalog/search-query/search-query-format.js +5 -1
  126. package/queries/catalog/static-slice-query/static-slice-query-format.d.ts +2 -0
  127. package/queries/catalog/static-slice-query/static-slice-query-format.js +9 -1
  128. package/queries/query.d.ts +143 -1
  129. package/queries/query.js +4 -0
  130. package/r-bridge/lang-4.x/tree-sitter/tree-sitter-normalize.js +11 -4
  131. package/r-bridge/retriever.js +1 -1
  132. package/search/flowr-search-builder.d.ts +31 -2
  133. package/search/flowr-search-builder.js +30 -0
  134. package/search/flowr-search.d.ts +7 -1
  135. package/search/search-executor/search-enrichers.d.ts +73 -0
  136. package/search/search-executor/search-enrichers.js +101 -0
  137. package/search/search-executor/search-generators.d.ts +6 -1
  138. package/search/search-executor/search-generators.js +21 -1
  139. package/search/search-executor/search-mappers.d.ts +19 -0
  140. package/search/search-executor/search-mappers.js +21 -0
  141. package/search/search-executor/search-transformer.d.ts +12 -0
  142. package/search/search-executor/search-transformer.js +11 -1
  143. package/slicing/criterion/parse.d.ts +8 -0
  144. package/slicing/criterion/parse.js +20 -0
  145. package/util/version.js +1 -1
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ResolvedCallSuffix = void 0;
4
- exports.extractCFG = extractCFG;
4
+ exports.extractCfg = extractCfg;
5
5
  exports.extractSimpleCfg = extractSimpleCfg;
6
6
  exports.cfg2quads = cfg2quads;
7
7
  const quads_1 = require("../util/quads");
@@ -62,20 +62,18 @@ function dataflowCfgFolds(dataflowGraph) {
62
62
  *
63
63
  * @see {@link extractSimpleCfg} - for a simplified version of this function
64
64
  */
65
- function extractCFG(ast, graph, simplifications) {
66
- return (0, cfg_simplification_1.simplifyControlFlowInformation)((0, fold_1.foldAst)(ast.ast, graph ? dataflowCfgFolds(graph) : cfgFolds), simplifications);
65
+ function extractCfg(ast, graph, simplifications) {
66
+ return (0, cfg_simplification_1.simplifyControlFlowInformation)((0, fold_1.foldAst)(ast.ast, graph ? dataflowCfgFolds(graph) : cfgFolds), { ast, dfg: graph }, simplifications);
67
67
  }
68
68
  /**
69
- * Simplified version of {@link extractCFG} that is much quicker, but much simpler!
69
+ * Simplified version of {@link extractCfg} that is much quicker, but much simpler!
70
70
  */
71
71
  function extractSimpleCfg(ast) {
72
72
  return (0, fold_1.foldAst)(ast.ast, cfgFolds);
73
73
  }
74
74
  function cfgLeaf(type) {
75
- return (leaf) => {
76
- const graph = new control_flow_graph_1.ControlFlowGraph();
77
- graph.addVertex({ id: leaf.info.id, type });
78
- return { graph, breaks: [], nexts: [], returns: [], exitPoints: [leaf.info.id], entryPoints: [leaf.info.id] };
75
+ return ({ info: { id } }) => {
76
+ return { graph: new control_flow_graph_1.ControlFlowGraph().addVertex({ id, type }), breaks: [], nexts: [], returns: [], exitPoints: [id], entryPoints: [id] };
79
77
  };
80
78
  }
81
79
  function cfgBreak(leaf) {
@@ -91,40 +89,41 @@ function identifyMayStatementType(node) {
91
89
  return node.info.role === "expr-list-child" /* RoleInParent.ExpressionListChild */ ? control_flow_graph_1.CfgVertexType.Statement : control_flow_graph_1.CfgVertexType.Expression;
92
90
  }
93
91
  function cfgIfThenElse(ifNode, condition, then, otherwise) {
92
+ const ifId = ifNode.info.id;
94
93
  const graph = new control_flow_graph_1.ControlFlowGraph();
95
- graph.addVertex({ id: ifNode.info.id, type: identifyMayStatementType(ifNode), mid: [ifNode.info.id + '-condition'], end: [ifNode.info.id + '-exit'] });
96
- graph.addVertex({ id: ifNode.info.id + '-condition', kind: 'condition', type: control_flow_graph_1.CfgVertexType.MidMarker, root: ifNode.info.id });
97
- graph.addVertex({ id: ifNode.info.id + '-exit', type: control_flow_graph_1.CfgVertexType.EndMarker, root: ifNode.info.id });
94
+ graph.addVertex({ id: ifId, type: identifyMayStatementType(ifNode), mid: [ifId + '-condition'], end: [ifId + '-exit'] });
95
+ graph.addVertex({ id: ifId + '-condition', kind: 'condition', type: control_flow_graph_1.CfgVertexType.MidMarker, root: ifId });
96
+ graph.addVertex({ id: ifId + '-exit', type: control_flow_graph_1.CfgVertexType.EndMarker, root: ifId });
98
97
  graph.mergeWith(condition.graph);
99
98
  graph.mergeWith(then.graph);
100
99
  if (otherwise) {
101
100
  graph.mergeWith(otherwise.graph);
102
101
  }
103
102
  for (const exitPoint of condition.exitPoints) {
104
- graph.addEdge(ifNode.info.id + '-condition', exitPoint, { label: 0 /* CfgEdgeType.Fd */ });
103
+ graph.addEdge(ifId + '-condition', exitPoint, { label: 0 /* CfgEdgeType.Fd */ });
105
104
  }
106
105
  for (const entryPoint of then.entryPoints) {
107
- graph.addEdge(entryPoint, ifNode.info.id + '-condition', { label: 1 /* CfgEdgeType.Cd */, when: convert_values_1.RTrue, caused: ifNode.info.id });
106
+ graph.addEdge(entryPoint, ifId + '-condition', { label: 1 /* CfgEdgeType.Cd */, when: convert_values_1.RTrue, caused: ifId });
108
107
  }
109
108
  for (const entryPoint of otherwise?.entryPoints ?? []) {
110
- graph.addEdge(entryPoint, ifNode.info.id + '-condition', { label: 1 /* CfgEdgeType.Cd */, when: convert_values_1.RFalse, caused: ifNode.info.id });
109
+ graph.addEdge(entryPoint, ifId + '-condition', { label: 1 /* CfgEdgeType.Cd */, when: convert_values_1.RFalse, caused: ifId });
111
110
  }
112
111
  for (const entryPoint of condition.entryPoints) {
113
- graph.addEdge(entryPoint, ifNode.info.id, { label: 0 /* CfgEdgeType.Fd */ });
112
+ graph.addEdge(entryPoint, ifId, { label: 0 /* CfgEdgeType.Fd */ });
114
113
  }
115
114
  for (const exit of [...then.exitPoints, ...otherwise?.exitPoints ?? []]) {
116
- graph.addEdge(ifNode.info.id + '-exit', exit, { label: 0 /* CfgEdgeType.Fd */ });
115
+ graph.addEdge(ifId + '-exit', exit, { label: 0 /* CfgEdgeType.Fd */ });
117
116
  }
118
117
  if (!otherwise) {
119
- graph.addEdge(ifNode.info.id + '-exit', ifNode.info.id + '-condition', { label: 1 /* CfgEdgeType.Cd */, when: convert_values_1.RFalse, caused: ifNode.info.id });
118
+ graph.addEdge(ifId + '-exit', ifId + '-condition', { label: 1 /* CfgEdgeType.Cd */, when: convert_values_1.RFalse, caused: ifId });
120
119
  }
121
120
  return {
122
121
  graph,
123
122
  breaks: [...then.breaks, ...otherwise?.breaks ?? []],
124
123
  nexts: [...then.nexts, ...otherwise?.nexts ?? []],
125
124
  returns: [...then.returns, ...otherwise?.returns ?? []],
126
- exitPoints: [ifNode.info.id + '-exit'],
127
- entryPoints: [ifNode.info.id]
125
+ exitPoints: [ifId + '-exit'],
126
+ entryPoints: [ifId]
128
127
  };
129
128
  }
130
129
  function cfgRepeat(repeat, body) {
@@ -144,110 +143,114 @@ function cfgRepeat(repeat, body) {
144
143
  return { graph, breaks: [], nexts: [], returns: body.returns, exitPoints: [repeat.info.id + '-exit'], entryPoints: [repeat.info.id] };
145
144
  }
146
145
  function cfgWhile(whileLoop, condition, body) {
146
+ const whileId = whileLoop.info.id;
147
147
  const graph = condition.graph;
148
- graph.addVertex({ id: whileLoop.info.id, type: identifyMayStatementType(whileLoop), mid: [whileLoop.info.id + '-condition'], end: [whileLoop.info.id + '-exit'] });
149
- graph.addVertex({ id: whileLoop.info.id + '-condition', kind: 'condition', type: control_flow_graph_1.CfgVertexType.MidMarker, root: whileLoop.info.id });
150
- graph.addVertex({ id: whileLoop.info.id + '-exit', type: control_flow_graph_1.CfgVertexType.EndMarker, root: whileLoop.info.id });
148
+ graph.addVertex({ id: whileId, type: identifyMayStatementType(whileLoop), mid: [whileId + '-condition'], end: [whileId + '-exit'] });
149
+ graph.addVertex({ id: whileId + '-condition', kind: 'condition', type: control_flow_graph_1.CfgVertexType.MidMarker, root: whileId });
150
+ graph.addVertex({ id: whileId + '-exit', type: control_flow_graph_1.CfgVertexType.EndMarker, root: whileId });
151
151
  graph.mergeWith(body.graph);
152
152
  for (const entry of condition.entryPoints) {
153
- graph.addEdge(entry, whileLoop.info.id, { label: 0 /* CfgEdgeType.Fd */ });
153
+ graph.addEdge(entry, whileId, { label: 0 /* CfgEdgeType.Fd */ });
154
154
  }
155
155
  for (const exit of condition.exitPoints) {
156
- graph.addEdge(whileLoop.info.id + '-condition', exit, { label: 0 /* CfgEdgeType.Fd */ });
156
+ graph.addEdge(whileId + '-condition', exit, { label: 0 /* CfgEdgeType.Fd */ });
157
157
  }
158
158
  for (const entry of body.entryPoints) {
159
- graph.addEdge(entry, whileLoop.info.id + '-condition', { label: 1 /* CfgEdgeType.Cd */, when: convert_values_1.RTrue, caused: whileLoop.info.id });
159
+ graph.addEdge(entry, whileId + '-condition', { label: 1 /* CfgEdgeType.Cd */, when: convert_values_1.RTrue, caused: whileId });
160
160
  }
161
161
  for (const next of [...body.nexts, ...body.exitPoints]) {
162
- graph.addEdge(whileLoop.info.id, next, { label: 0 /* CfgEdgeType.Fd */ });
162
+ graph.addEdge(whileId, next, { label: 0 /* CfgEdgeType.Fd */ });
163
163
  }
164
164
  for (const breakPoint of body.breaks) {
165
- graph.addEdge(whileLoop.info.id + '-exit', breakPoint, { label: 0 /* CfgEdgeType.Fd */ });
165
+ graph.addEdge(whileId + '-exit', breakPoint, { label: 0 /* CfgEdgeType.Fd */ });
166
166
  }
167
167
  // while can break on the condition as well
168
- graph.addEdge(whileLoop.info.id + '-exit', whileLoop.info.id + '-condition', { label: 1 /* CfgEdgeType.Cd */, when: convert_values_1.RFalse, caused: whileLoop.info.id });
169
- return { graph, breaks: [], nexts: [], returns: body.returns, exitPoints: [whileLoop.info.id + '-exit'], entryPoints: [whileLoop.info.id] };
168
+ graph.addEdge(whileId + '-exit', whileId + '-condition', { label: 1 /* CfgEdgeType.Cd */, when: convert_values_1.RFalse, caused: whileId });
169
+ return { graph, breaks: [], nexts: [], returns: body.returns, exitPoints: [whileId + '-exit'], entryPoints: [whileId] };
170
170
  }
171
171
  function cfgFor(forLoop, variable, vector, body) {
172
+ const forLoopId = forLoop.info.id;
172
173
  const graph = variable.graph;
173
- graph.addVertex({ id: forLoop.info.id, type: identifyMayStatementType(forLoop), end: [forLoop.info.id + '-exit'], mid: [forLoop.info.id + '-head'] });
174
+ graph.addVertex({ id: forLoopId, type: identifyMayStatementType(forLoop), end: [forLoopId + '-exit'], mid: [forLoopId + '-head'] });
174
175
  graph.mergeWith(vector.graph);
175
176
  graph.mergeWith(body.graph);
176
177
  for (const entry of vector.entryPoints) {
177
- graph.addEdge(entry, forLoop.info.id, { label: 0 /* CfgEdgeType.Fd */ });
178
+ graph.addEdge(entry, forLoopId, { label: 0 /* CfgEdgeType.Fd */ });
178
179
  }
179
180
  for (const exit of vector.exitPoints) {
180
181
  for (const entry of variable.entryPoints) {
181
182
  graph.addEdge(entry, exit, { label: 0 /* CfgEdgeType.Fd */ });
182
183
  }
183
184
  }
184
- graph.addVertex({ id: forLoop.info.id + '-head', type: control_flow_graph_1.CfgVertexType.MidMarker, root: forLoop.info.id, kind: 'head' });
185
+ graph.addVertex({ id: forLoopId + '-head', type: control_flow_graph_1.CfgVertexType.MidMarker, root: forLoopId, kind: 'head' });
185
186
  for (const exit of variable.exitPoints) {
186
- graph.addEdge(forLoop.info.id + '-head', exit, { label: 0 /* CfgEdgeType.Fd */ });
187
+ graph.addEdge(forLoopId + '-head', exit, { label: 0 /* CfgEdgeType.Fd */ });
187
188
  }
188
189
  for (const entry of body.entryPoints) {
189
- graph.addEdge(entry, forLoop.info.id + '-head', { label: 1 /* CfgEdgeType.Cd */, when: convert_values_1.RTrue, caused: forLoop.info.id });
190
+ graph.addEdge(entry, forLoopId + '-head', { label: 1 /* CfgEdgeType.Cd */, when: convert_values_1.RTrue, caused: forLoopId });
190
191
  }
191
192
  for (const next of [...body.nexts, ...body.exitPoints]) {
192
- graph.addEdge(forLoop.info.id, next, { label: 0 /* CfgEdgeType.Fd */ });
193
+ graph.addEdge(forLoopId, next, { label: 0 /* CfgEdgeType.Fd */ });
193
194
  }
194
195
  for (const breakPoint of body.breaks) {
195
- graph.addEdge(forLoop.info.id + '-exit', breakPoint, { label: 0 /* CfgEdgeType.Fd */ });
196
+ graph.addEdge(forLoopId + '-exit', breakPoint, { label: 0 /* CfgEdgeType.Fd */ });
196
197
  }
197
198
  const isNotEndless = body.exitPoints.length > 0 || body.breaks.length > 0;
198
199
  if (isNotEndless) {
199
200
  graph.addVertex({
200
- id: forLoop.info.id + '-exit',
201
+ id: forLoopId + '-exit',
201
202
  type: control_flow_graph_1.CfgVertexType.EndMarker,
202
- root: forLoop.info.id
203
+ root: forLoopId
203
204
  });
204
- graph.addEdge(forLoop.info.id + '-exit', forLoop.info.id + '-head', { label: 1 /* CfgEdgeType.Cd */, when: convert_values_1.RFalse, caused: forLoop.info.id });
205
+ graph.addEdge(forLoopId + '-exit', forLoopId + '-head', { label: 1 /* CfgEdgeType.Cd */, when: convert_values_1.RFalse, caused: forLoopId });
205
206
  }
206
- return { graph, breaks: [], nexts: [], returns: body.returns, exitPoints: isNotEndless ? [forLoop.info.id + '-exit'] : [], entryPoints: [forLoop.info.id] };
207
+ return { graph, breaks: [], nexts: [], returns: body.returns, exitPoints: isNotEndless ? [forLoopId + '-exit'] : [], entryPoints: [forLoopId] };
207
208
  }
208
209
  function cfgFunctionDefinition(fn, params, body) {
210
+ const fnId = fn.info.id;
209
211
  const graph = new control_flow_graph_1.ControlFlowGraph();
210
- const children = [fn.info.id + '-params', fn.info.id + '-exit'];
211
- graph.addVertex({ id: fn.info.id + '-params', kind: 'parameters', type: control_flow_graph_1.CfgVertexType.MidMarker, root: fn.info.id }, false);
212
- graph.addVertex({ id: fn.info.id + '-exit', type: control_flow_graph_1.CfgVertexType.EndMarker, root: fn.info.id }, false);
213
- graph.addVertex({ id: fn.info.id, children, type: identifyMayStatementType(fn), mid: [fn.info.id + '-params'], end: [fn.info.id + '-exit'] });
212
+ const children = [fnId + '-params', fnId + '-exit'];
213
+ graph.addVertex({ id: fnId + '-params', kind: 'parameters', type: control_flow_graph_1.CfgVertexType.MidMarker, root: fnId }, false);
214
+ graph.addVertex({ id: fnId + '-exit', type: control_flow_graph_1.CfgVertexType.EndMarker, root: fnId }, false);
215
+ graph.addVertex({ id: fnId, children, type: identifyMayStatementType(fn), mid: [fnId + '-params'], end: [fnId + '-exit'] });
214
216
  graph.mergeWith(body.graph, true);
215
217
  children.push(...body.graph.rootIds());
216
218
  for (const param of params) {
217
219
  graph.mergeWith(param.graph, true);
218
220
  children.push(...param.graph.rootIds());
219
221
  for (const entry of param.entryPoints) {
220
- graph.addEdge(entry, fn.info.id, { label: 0 /* CfgEdgeType.Fd */ });
222
+ graph.addEdge(entry, fnId, { label: 0 /* CfgEdgeType.Fd */ });
221
223
  }
222
224
  for (const exit of param.exitPoints) {
223
- graph.addEdge(fn.info.id + '-params', exit, { label: 0 /* CfgEdgeType.Fd */ });
225
+ graph.addEdge(fnId + '-params', exit, { label: 0 /* CfgEdgeType.Fd */ });
224
226
  }
225
227
  }
226
228
  if (params.length === 0) {
227
- graph.addEdge(fn.info.id + '-params', fn.info.id, { label: 0 /* CfgEdgeType.Fd */ });
229
+ graph.addEdge(fnId + '-params', fnId, { label: 0 /* CfgEdgeType.Fd */ });
228
230
  }
229
231
  for (const entry of body.entryPoints) {
230
- graph.addEdge(entry, fn.info.id + '-params', { label: 0 /* CfgEdgeType.Fd */ });
232
+ graph.addEdge(entry, fnId + '-params', { label: 0 /* CfgEdgeType.Fd */ });
231
233
  }
232
- // breaks and nexts should be illegal but safe is safe i guess
233
- for (const next of [...body.returns, ...body.breaks, ...body.nexts, ...body.exitPoints]) {
234
- graph.addEdge(fn.info.id + '-exit', next, { label: 0 /* CfgEdgeType.Fd */ });
234
+ // breaks and nexts should be illegal but safe is safe, I guess
235
+ for (const next of body.returns.concat(body.breaks, body.nexts, body.exitPoints)) {
236
+ graph.addEdge(fnId + '-exit', next, { label: 0 /* CfgEdgeType.Fd */ });
235
237
  }
236
- return { graph: graph, breaks: [], nexts: [], returns: [], exitPoints: [fn.info.id], entryPoints: [fn.info.id] };
238
+ return { graph: graph, breaks: [], nexts: [], returns: [], exitPoints: [fnId], entryPoints: [fnId] };
237
239
  }
238
240
  function cfgFunctionCall(call, name, args, exit = 'exit') {
241
+ const callId = call.info.id;
239
242
  const graph = name.graph;
240
- const info = { graph, breaks: [...name.breaks], nexts: [...name.nexts], returns: [...name.returns], exitPoints: [call.info.id + '-' + exit], entryPoints: [call.info.id] };
241
- graph.addVertex({ id: call.info.id, type: identifyMayStatementType(call), mid: [call.info.id + '-name'], end: [call.info.id + '-' + exit] });
243
+ const info = { graph, breaks: [...name.breaks], nexts: [...name.nexts], returns: [...name.returns], exitPoints: [callId + '-' + exit], entryPoints: [callId] };
244
+ graph.addVertex({ id: callId, type: identifyMayStatementType(call), mid: [callId + '-name'], end: [callId + '-' + exit] });
242
245
  for (const entryPoint of name.entryPoints) {
243
- graph.addEdge(entryPoint, call.info.id, { label: 0 /* CfgEdgeType.Fd */ });
246
+ graph.addEdge(entryPoint, callId, { label: 0 /* CfgEdgeType.Fd */ });
244
247
  }
245
- graph.addVertex({ id: call.info.id + '-name', kind: 'name', type: control_flow_graph_1.CfgVertexType.MidMarker, root: call.info.id });
248
+ graph.addVertex({ id: callId + '-name', kind: 'name', type: control_flow_graph_1.CfgVertexType.MidMarker, root: callId });
246
249
  for (const exitPoint of name.exitPoints) {
247
- graph.addEdge(call.info.id + '-name', exitPoint, { label: 0 /* CfgEdgeType.Fd */ });
250
+ graph.addEdge(callId + '-name', exitPoint, { label: 0 /* CfgEdgeType.Fd */ });
248
251
  }
249
- graph.addVertex({ id: call.info.id + '-' + exit, type: control_flow_graph_1.CfgVertexType.EndMarker, root: call.info.id });
250
- let lastArgExits = [call.info.id + '-name'];
252
+ graph.addVertex({ id: callId + '-' + exit, type: control_flow_graph_1.CfgVertexType.EndMarker, root: callId });
253
+ let lastArgExits = [callId + '-name'];
251
254
  for (const arg of args) {
252
255
  if (arg === r_function_call_1.EmptyArgument) {
253
256
  continue;
@@ -264,7 +267,7 @@ function cfgFunctionCall(call, name, args, exit = 'exit') {
264
267
  lastArgExits = arg.exitPoints;
265
268
  }
266
269
  for (const exit of lastArgExits) {
267
- graph.addEdge(call.info.id + '-exit', exit, { label: 0 /* CfgEdgeType.Fd */ });
270
+ graph.addEdge(callId + '-exit', exit, { label: 0 /* CfgEdgeType.Fd */ });
268
271
  }
269
272
  // should not contain any breaks, nexts, or returns, (except for the body if something like 'break()')
270
273
  return info;
@@ -272,11 +275,11 @@ function cfgFunctionCall(call, name, args, exit = 'exit') {
272
275
  exports.ResolvedCallSuffix = '-resolved-call-exit';
273
276
  function cfgFunctionCallWithDataflow(graph) {
274
277
  return (call, name, args) => {
275
- const baseCFG = cfgFunctionCall(call, name, args);
278
+ const baseCfg = cfgFunctionCall(call, name, args);
276
279
  /* try to resolve the call and link the target definitions */
277
280
  const targets = (0, linker_1.getAllFunctionCallTargets)(call.info.id, graph);
278
281
  const exits = [];
279
- const callVertex = baseCFG.graph.getVertex(call.info.id);
282
+ const callVertex = baseCfg.graph.getVertex(call.info.id);
280
283
  (0, assert_1.guard)(callVertex !== undefined, 'cfgFunctionCallWithDataflow: call vertex not found');
281
284
  for (const target of targets) {
282
285
  // we have to filter out non func-call targets as the call targets contains names and call ids
@@ -287,21 +290,21 @@ function cfgFunctionCallWithDataflow(graph) {
287
290
  }
288
291
  }
289
292
  if (exits.length > 0) {
290
- baseCFG.graph.addVertex({
293
+ baseCfg.graph.addVertex({
291
294
  id: call.info.id + exports.ResolvedCallSuffix,
292
295
  type: control_flow_graph_1.CfgVertexType.EndMarker,
293
296
  root: call.info.id
294
297
  });
295
- for (const exit of [...baseCFG.exitPoints, ...exits]) {
296
- baseCFG.graph.addEdge(call.info.id + exports.ResolvedCallSuffix, exit, { label: 0 /* CfgEdgeType.Fd */ });
298
+ for (const exit of [...baseCfg.exitPoints, ...exits]) {
299
+ baseCfg.graph.addEdge(call.info.id + exports.ResolvedCallSuffix, exit, { label: 0 /* CfgEdgeType.Fd */ });
297
300
  }
298
301
  return {
299
- ...baseCFG,
302
+ ...baseCfg,
300
303
  exitPoints: [call.info.id + exports.ResolvedCallSuffix]
301
304
  };
302
305
  }
303
306
  else {
304
- return baseCFG;
307
+ return baseCfg;
305
308
  }
306
309
  };
307
310
  }
@@ -1,5 +1,4 @@
1
1
  import type { CfgExpressionVertex, CfgStatementVertex, ControlFlowInformation } from './control-flow-graph';
2
- import type { DataflowInformation } from '../dataflow/info';
3
2
  import type { DataflowCfgGuidedVisitorConfiguration } from './dfg-cfg-guided-visitor';
4
3
  import { DataflowAwareCfgGuidedVisitor } from './dfg-cfg-guided-visitor';
5
4
  import type { NormalizedAst, ParentInformation } from '../r-bridge/lang-4.x/ast/model/processing/decorate';
@@ -10,12 +9,12 @@ import type { DataflowGraphVertexFunctionCall, DataflowGraphVertexFunctionDefini
10
9
  import type { RString } from '../r-bridge/lang-4.x/ast/model/nodes/r-string';
11
10
  import type { RNumber } from '../r-bridge/lang-4.x/ast/model/nodes/r-number';
12
11
  import type { RLogical } from '../r-bridge/lang-4.x/ast/model/nodes/r-logical';
13
- import type { FunctionArgument } from '../dataflow/graph/graph';
12
+ import type { DataflowGraph, FunctionArgument } from '../dataflow/graph/graph';
14
13
  import type { NoInfo, RNode } from '../r-bridge/lang-4.x/ast/model/model';
15
14
  import type { RSymbol } from '../r-bridge/lang-4.x/ast/model/nodes/r-symbol';
16
15
  import type { BuiltInProcessorMapper } from '../dataflow/environments/built-in';
17
16
  import type { RExpressionList } from '../r-bridge/lang-4.x/ast/model/nodes/r-expression-list';
18
- export interface SemanticCfgGuidedVisitorConfiguration<OtherInfo = NoInfo, Cfg extends ControlFlowInformation = ControlFlowInformation, Ast extends NormalizedAst<OtherInfo> = NormalizedAst<OtherInfo>, Dfg extends DataflowInformation = DataflowInformation> extends DataflowCfgGuidedVisitorConfiguration<Cfg, Dfg>, SyntaxCfgGuidedVisitorConfiguration<OtherInfo, Cfg, Ast> {
17
+ export interface SemanticCfgGuidedVisitorConfiguration<OtherInfo = NoInfo, ControlFlow extends ControlFlowInformation = ControlFlowInformation, Ast extends NormalizedAst<OtherInfo> = NormalizedAst<OtherInfo>, Dfg extends DataflowGraph = DataflowGraph> extends DataflowCfgGuidedVisitorConfiguration<ControlFlow, Dfg>, SyntaxCfgGuidedVisitorConfiguration<OtherInfo, ControlFlow, Ast> {
19
18
  }
20
19
  /**
21
20
  * This visitor extends on the {@link DataflowAwareCfgGuidedVisitor} by dispatching visitors for separate function calls as well,
@@ -40,7 +39,7 @@ export interface SemanticCfgGuidedVisitorConfiguration<OtherInfo = NoInfo, Cfg e
40
39
  *
41
40
  * Use {@link BasicCfgGuidedVisitor#start} to start the traversal.
42
41
  */
43
- export declare class SemanticCfgGuidedVisitor<OtherInfo = NoInfo, Cfg extends ControlFlowInformation = ControlFlowInformation, Ast extends NormalizedAst<OtherInfo> = NormalizedAst<OtherInfo>, Dfg extends DataflowInformation = DataflowInformation, Config extends SemanticCfgGuidedVisitorConfiguration<OtherInfo, Cfg, Ast, Dfg> = SemanticCfgGuidedVisitorConfiguration<OtherInfo, Cfg, Ast, Dfg>> extends DataflowAwareCfgGuidedVisitor<Cfg, Dfg, Config> {
42
+ export declare class SemanticCfgGuidedVisitor<OtherInfo = NoInfo, ControlFlow extends ControlFlowInformation = ControlFlowInformation, Ast extends NormalizedAst<OtherInfo> = NormalizedAst<OtherInfo>, Dfg extends DataflowGraph = DataflowGraph, Config extends SemanticCfgGuidedVisitorConfiguration<OtherInfo, ControlFlow, Ast, Dfg> = SemanticCfgGuidedVisitorConfiguration<OtherInfo, ControlFlow, Ast, Dfg>> extends DataflowAwareCfgGuidedVisitor<ControlFlow, Dfg, Config> {
44
43
  /**
45
44
  * A helper function to get the normalized AST node for the given id or fail if it does not exist.
46
45
  */
@@ -117,6 +116,11 @@ export declare class SemanticCfgGuidedVisitor<OtherInfo = NoInfo, Cfg extends Co
117
116
  * @protected
118
117
  */
119
118
  protected onDispatchFunctionCallOrigin(call: DataflowGraphVertexFunctionCall, origin: keyof typeof BuiltInProcessorMapper | string): void;
119
+ /**
120
+ * This event is called for the root program node, i.e., the program that is being analyzed.
121
+ *
122
+ * @protected
123
+ */
120
124
  protected onProgram(_data: RExpressionList<OtherInfo>): void;
121
125
  /**
122
126
  * A helper function to request the {@link getOriginInDfg|origins} of the given node.
@@ -180,6 +184,7 @@ export declare class SemanticCfgGuidedVisitor<OtherInfo = NoInfo, Cfg extends Co
180
184
  */
181
185
  protected onFunctionDefinition(_data: {
182
186
  vertex: DataflowGraphVertexFunctionDefinition;
187
+ parameters?: readonly NodeId[];
183
188
  }): void;
184
189
  /**
185
190
  * This event triggers for every anonymous call within the program.
@@ -211,7 +216,7 @@ export declare class SemanticCfgGuidedVisitor<OtherInfo = NoInfo, Cfg extends Co
211
216
  *
212
217
  * This explicitly will not trigger for scenarios in which the function has no name (i.e., if it is anonymous).
213
218
  * For such cases, you may rely on the {@link SemanticCfgGuidedVisitor#onUnnamedCall|`onUnnamedCall`} event.
214
- * The main reason for this separation is part of flowR's handling of these functions, as anonmyous calls cannot be resolved using the active environment.
219
+ * The main reason for this separation is part of flowR's handling of these functions, as anonymous calls cannot be resolved using the active environment.
215
220
  *
216
221
  * @protected
217
222
  */
@@ -282,9 +287,9 @@ export declare class SemanticCfgGuidedVisitor<OtherInfo = NoInfo, Cfg extends Co
282
287
  */
283
288
  protected onIfThenElseCall(_data: {
284
289
  call: DataflowGraphVertexFunctionCall;
285
- condition: FunctionArgument;
286
- then: FunctionArgument;
287
- else: FunctionArgument | undefined;
290
+ condition: NodeId | undefined;
291
+ then: NodeId | undefined;
292
+ else: NodeId | undefined;
288
293
  }): void;
289
294
  /**
290
295
  * This event triggers for every call to the `get` function, which is used to access variables in the global environment.
@@ -346,6 +351,8 @@ export declare class SemanticCfgGuidedVisitor<OtherInfo = NoInfo, Cfg extends Co
346
351
  */
347
352
  protected onSpecialBinaryOpCall(_data: {
348
353
  call: DataflowGraphVertexFunctionCall;
354
+ lhs?: FunctionArgument;
355
+ rhs?: FunctionArgument;
349
356
  }): void;
350
357
  /**
351
358
  * This event triggers for every call to R's pipe operator, i.e., for every call to `|>`.
@@ -354,6 +361,8 @@ export declare class SemanticCfgGuidedVisitor<OtherInfo = NoInfo, Cfg extends Co
354
361
  */
355
362
  protected onPipeCall(_data: {
356
363
  call: DataflowGraphVertexFunctionCall;
364
+ lhs?: FunctionArgument;
365
+ rhs?: FunctionArgument;
357
366
  }): void;
358
367
  /**
359
368
  * This event triggers for every call to the `quote` function, which is used to quote expressions.
@@ -6,6 +6,7 @@ const dfg_get_origin_1 = require("../dataflow/origin/dfg-get-origin");
6
6
  const type_1 = require("../r-bridge/lang-4.x/ast/model/type");
7
7
  const edge_1 = require("../dataflow/graph/edge");
8
8
  const assert_1 = require("../util/assert");
9
+ const r_function_call_1 = require("../r-bridge/lang-4.x/ast/model/nodes/r-function-call");
9
10
  /**
10
11
  * This visitor extends on the {@link DataflowAwareCfgGuidedVisitor} by dispatching visitors for separate function calls as well,
11
12
  * providing more information!
@@ -90,7 +91,13 @@ class SemanticCfgGuidedVisitor extends dfg_cfg_guided_visitor_1.DataflowAwareCfg
90
91
  */
91
92
  visitFunctionDefinition(vertex) {
92
93
  super.visitFunctionDefinition(vertex);
93
- this.onFunctionDefinition({ vertex });
94
+ const ast = this.getNormalizedAst(vertex.id);
95
+ if (ast?.type === type_1.RType.FunctionDefinition) {
96
+ this.onFunctionDefinition({ vertex, parameters: ast.parameters.map(p => p.info.id) });
97
+ }
98
+ else {
99
+ this.onFunctionDefinition({ vertex });
100
+ }
94
101
  }
95
102
  /**
96
103
  * See {@link DataflowAwareCfgGuidedVisitor#visitFunctionCall} for the base implementation.
@@ -161,8 +168,26 @@ class SemanticCfgGuidedVisitor extends dfg_cfg_guided_visitor_1.DataflowAwareCfg
161
168
  return this.onSourceCall({ call });
162
169
  case 'builtin:access':
163
170
  return this.onAccessCall({ call });
164
- case 'builtin:if-then-else':
165
- return this.onIfThenElseCall({ call, condition: call.args[0], then: call.args[1], else: call.args[2] });
171
+ case 'builtin:if-then-else': {
172
+ // recover dead arguments from ast
173
+ const ast = this.getNormalizedAst(call.id);
174
+ if (!ast || ast.type !== type_1.RType.IfThenElse) {
175
+ return this.onIfThenElseCall({
176
+ call,
177
+ condition: call.args[0] === r_function_call_1.EmptyArgument ? undefined : call.args[0].nodeId,
178
+ then: call.args[1] === r_function_call_1.EmptyArgument ? undefined : call.args[1].nodeId,
179
+ else: call.args[2] === r_function_call_1.EmptyArgument ? undefined : call.args[2].nodeId
180
+ });
181
+ }
182
+ else {
183
+ return this.onIfThenElseCall({
184
+ call,
185
+ condition: ast.condition.info.id,
186
+ then: ast.then.info.id,
187
+ else: ast.otherwise?.info.id
188
+ });
189
+ }
190
+ }
166
191
  case 'builtin:get':
167
192
  return this.onGetCall({ call });
168
193
  case 'builtin:rm':
@@ -173,11 +198,11 @@ class SemanticCfgGuidedVisitor extends dfg_cfg_guided_visitor_1.DataflowAwareCfg
173
198
  return this.onVectorCall({ call });
174
199
  case 'table:assign':
175
200
  case 'builtin:assignment': {
176
- const outgoing = this.config.dataflow.graph.outgoingEdges(call.id);
201
+ const outgoing = this.config.dfg.outgoingEdges(call.id);
177
202
  if (outgoing) {
178
203
  const target = [...outgoing.entries()].filter(([, e]) => (0, edge_1.edgeIncludesType)(e.types, edge_1.EdgeType.Returns));
179
204
  if (target.length === 1) {
180
- const targetOut = this.config.dataflow.graph.outgoingEdges(target[0][0]);
205
+ const targetOut = this.config.dfg.outgoingEdges(target[0][0]);
181
206
  if (targetOut) {
182
207
  const source = [...targetOut.entries()].filter(([t, e]) => (0, edge_1.edgeIncludesType)(e.types, edge_1.EdgeType.DefinedBy) && t !== call.id);
183
208
  if (source.length === 1) {
@@ -189,9 +214,15 @@ class SemanticCfgGuidedVisitor extends dfg_cfg_guided_visitor_1.DataflowAwareCfg
189
214
  return this.onAssignmentCall({ call, target: undefined, source: undefined });
190
215
  }
191
216
  case 'builtin:special-bin-op':
192
- return this.onSpecialBinaryOpCall({ call });
217
+ if (call.args.length !== 2) {
218
+ return this.onSpecialBinaryOpCall({ call });
219
+ }
220
+ return this.onSpecialBinaryOpCall({ call, lhs: call.args[0], rhs: call.args[1] });
193
221
  case 'builtin:pipe':
194
- return this.onPipeCall({ call });
222
+ if (call.args.length !== 2) {
223
+ return this.onPipeCall({ call });
224
+ }
225
+ return this.onPipeCall({ call, lhs: call.args[0], rhs: call.args[1] });
195
226
  case 'builtin:quote':
196
227
  return this.onQuoteCall({ call });
197
228
  case 'builtin:for-loop':
@@ -201,11 +232,11 @@ class SemanticCfgGuidedVisitor extends dfg_cfg_guided_visitor_1.DataflowAwareCfg
201
232
  case 'builtin:while-loop':
202
233
  return this.onWhileLoopCall({ call, condition: call.args[0], body: call.args[1] });
203
234
  case 'builtin:replacement': {
204
- const outgoing = this.config.dataflow.graph.outgoingEdges(call.id);
235
+ const outgoing = this.config.dfg.outgoingEdges(call.id);
205
236
  if (outgoing) {
206
237
  const target = [...outgoing.entries()].filter(([, e]) => (0, edge_1.edgeIncludesType)(e.types, edge_1.EdgeType.Returns));
207
238
  if (target.length === 1) {
208
- const targetOut = this.config.dataflow.graph.outgoingEdges(target[0][0]);
239
+ const targetOut = this.config.dfg.outgoingEdges(target[0][0]);
209
240
  if (targetOut) {
210
241
  const source = [...targetOut.entries()].filter(([t, e]) => (0, edge_1.edgeIncludesType)(e.types, edge_1.EdgeType.DefinedBy) && t !== call.id);
211
242
  if (source.length === 1) {
@@ -223,13 +254,17 @@ class SemanticCfgGuidedVisitor extends dfg_cfg_guided_visitor_1.DataflowAwareCfg
223
254
  return this.onDefaultFunctionCall({ call });
224
255
  }
225
256
  }
226
- onProgram(_data) {
227
- }
257
+ /**
258
+ * This event is called for the root program node, i.e., the program that is being analyzed.
259
+ *
260
+ * @protected
261
+ */
262
+ onProgram(_data) { }
228
263
  /**
229
264
  * A helper function to request the {@link getOriginInDfg|origins} of the given node.
230
265
  */
231
266
  getOrigins(id) {
232
- return (0, dfg_get_origin_1.getOriginInDfg)(this.config.dataflow.graph, id);
267
+ return (0, dfg_get_origin_1.getOriginInDfg)(this.config.dfg, id);
233
268
  }
234
269
  /** Called for every occurrence of a `NULL` in the program. */
235
270
  onNullConstant(_data) { }
@@ -300,7 +335,7 @@ class SemanticCfgGuidedVisitor extends dfg_cfg_guided_visitor_1.DataflowAwareCfg
300
335
  *
301
336
  * This explicitly will not trigger for scenarios in which the function has no name (i.e., if it is anonymous).
302
337
  * For such cases, you may rely on the {@link SemanticCfgGuidedVisitor#onUnnamedCall|`onUnnamedCall`} event.
303
- * The main reason for this separation is part of flowR's handling of these functions, as anonmyous calls cannot be resolved using the active environment.
338
+ * The main reason for this separation is part of flowR's handling of these functions, as anonymous calls cannot be resolved using the active environment.
304
339
  *
305
340
  * @protected
306
341
  */
@@ -351,15 +386,13 @@ class SemanticCfgGuidedVisitor extends dfg_cfg_guided_visitor_1.DataflowAwareCfg
351
386
  *
352
387
  * @protected
353
388
  */
354
- onAccessCall(_data) {
355
- }
389
+ onAccessCall(_data) { }
356
390
  /**
357
391
  * This event triggers for every call to the `if` function, which is used to implement the `if-then-else` control flow.
358
392
  *
359
393
  * @protected
360
394
  */
361
- onIfThenElseCall(_data) {
362
- }
395
+ onIfThenElseCall(_data) { }
363
396
  /**
364
397
  * This event triggers for every call to the `get` function, which is used to access variables in the global environment.
365
398
  *
@@ -23,3 +23,7 @@ export declare function visitCfgInReverseOrder(graph: ControlFlowGraph, startNod
23
23
  * @see {@link visitCfgInReverseOrder} for a traversal in reversed order
24
24
  */
25
25
  export declare function visitCfgInOrder(graph: ControlFlowGraph, startNodes: readonly NodeId[], visitor: (node: NodeId) => boolean | void): void;
26
+ /**
27
+ * Check if a node can reach another node in the control flow graph.
28
+ */
29
+ export declare function canReach(graph: ControlFlowGraph, from: NodeId[], to: NodeId): boolean;
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.visitCfgInReverseOrder = visitCfgInReverseOrder;
4
4
  exports.visitCfgInOrder = visitCfgInOrder;
5
+ exports.canReach = canReach;
5
6
  const control_flow_graph_1 = require("./control-flow-graph");
6
7
  /**
7
8
  * Visit all nodes reachable from the start node in the control flow graph, traversing the dependencies but ignoring cycles.
@@ -77,4 +78,17 @@ visitor) {
77
78
  }
78
79
  }
79
80
  }
81
+ /**
82
+ * Check if a node can reach another node in the control flow graph.
83
+ */
84
+ function canReach(graph, from, to) {
85
+ let reached = false;
86
+ visitCfgInOrder(graph, from, node => {
87
+ if (node === to) {
88
+ reached = true;
89
+ return true;
90
+ }
91
+ });
92
+ return reached;
93
+ }
80
94
  //# sourceMappingURL=simple-visitor.js.map
@@ -25,7 +25,7 @@ import type { RNext } from '../r-bridge/lang-4.x/ast/model/nodes/r-next';
25
25
  import type { RNumber } from '../r-bridge/lang-4.x/ast/model/nodes/r-number';
26
26
  import type { RSymbol } from '../r-bridge/lang-4.x/ast/model/nodes/r-symbol';
27
27
  import type { NoInfo, RNode } from '../r-bridge/lang-4.x/ast/model/model';
28
- export interface SyntaxCfgGuidedVisitorConfiguration<OtherInfo = NoInfo, Cfg extends ControlFlowInformation = ControlFlowInformation, Ast extends NormalizedAst<OtherInfo> = NormalizedAst<OtherInfo>> extends BasicCfgGuidedVisitorConfiguration<Cfg> {
28
+ export interface SyntaxCfgGuidedVisitorConfiguration<OtherInfo = NoInfo, ControlFlow extends ControlFlowInformation = ControlFlowInformation, Ast extends NormalizedAst<OtherInfo> = NormalizedAst<OtherInfo>> extends BasicCfgGuidedVisitorConfiguration<ControlFlow> {
29
29
  readonly normalizedAst: Ast;
30
30
  }
31
31
  /**
@@ -33,7 +33,7 @@ export interface SyntaxCfgGuidedVisitorConfiguration<OtherInfo = NoInfo, Cfg ext
33
33
  *
34
34
  * Use {@link BasicCfgGuidedVisitor#start} to start the traversal.
35
35
  */
36
- export declare class SyntaxAwareCfgGuidedVisitor<OtherInfo = NoInfo, Cfg extends ControlFlowInformation = ControlFlowInformation, Ast extends NormalizedAst<OtherInfo> = NormalizedAst<OtherInfo>, Config extends SyntaxCfgGuidedVisitorConfiguration<OtherInfo, Cfg, Ast> = SyntaxCfgGuidedVisitorConfiguration<OtherInfo, Cfg, Ast>> extends BasicCfgGuidedVisitor<Cfg, Config> {
36
+ export declare class SyntaxAwareCfgGuidedVisitor<OtherInfo = NoInfo, ControlFlow extends ControlFlowInformation = ControlFlowInformation, Ast extends NormalizedAst<OtherInfo> = NormalizedAst<OtherInfo>, Config extends SyntaxCfgGuidedVisitorConfiguration<OtherInfo, ControlFlow, Ast> = SyntaxCfgGuidedVisitorConfiguration<OtherInfo, ControlFlow, Ast>> extends BasicCfgGuidedVisitor<ControlFlow, Config> {
37
37
  /**
38
38
  * Get the normalized AST node for the given id or fail if it does not exist.
39
39
  */
@@ -27,6 +27,7 @@ export interface BuiltInFunctionDefinition<BuiltInProcessor extends BuiltInMappi
27
27
  readonly type: 'function';
28
28
  readonly processor: BuiltInProcessor;
29
29
  readonly config?: ConfigOfBuiltInMappingName<BuiltInProcessor>;
30
+ readonly evalHandler?: string;
30
31
  }
31
32
  /**
32
33
  * Define a built-in replacement (like `[` or `$`) and the processor to use.
@@ -15,7 +15,7 @@ import { processQuote } from '../internal/process/functions/call/built-in/built-
15
15
  import { processFunctionDefinition } from '../internal/process/functions/call/built-in/built-in-function-definition';
16
16
  import { processExpressionList } from '../internal/process/functions/call/built-in/built-in-expression-list';
17
17
  import { processGet } from '../internal/process/functions/call/built-in/built-in-get';
18
- import type { ParentInformation } from '../../r-bridge/lang-4.x/ast/model/processing/decorate';
18
+ import type { AstIdMap, ParentInformation, RNodeWithParent } from '../../r-bridge/lang-4.x/ast/model/processing/decorate';
19
19
  import type { RFunctionArgument } from '../../r-bridge/lang-4.x/ast/model/nodes/r-function-call';
20
20
  import type { RSymbol } from '../../r-bridge/lang-4.x/ast/model/nodes/r-symbol';
21
21
  import type { NodeId } from '../../r-bridge/lang-4.x/ast/model/processing/node-id';
@@ -28,6 +28,10 @@ import { processList } from '../internal/process/functions/call/built-in/built-i
28
28
  import { processVector } from '../internal/process/functions/call/built-in/built-in-vector';
29
29
  import { processRm } from '../internal/process/functions/call/built-in/built-in-rm';
30
30
  import { processEvalCall } from '../internal/process/functions/call/built-in/built-in-eval';
31
+ import type { REnvironmentInformation } from './environment';
32
+ import type { Value } from '../eval/values/r-value';
33
+ import { resolveAsVector } from '../eval/resolve/resolve';
34
+ import type { DataflowGraph } from '../graph/graph';
31
35
  export type BuiltIn = `built-in:${string}`;
32
36
  export declare function builtInId(name: string): BuiltIn;
33
37
  export declare function isBuiltIn(name: NodeId | string): name is BuiltIn;
@@ -52,6 +56,7 @@ export interface DefaultBuiltInProcessorConfiguration extends ForceArguments {
52
56
  /** record mapping the actual function name called to the arguments that should be treated as function calls */
53
57
  readonly treatAsFnCall?: Record<string, readonly string[]>;
54
58
  }
59
+ export type BuiltInEvalHandler = (a: RNodeWithParent, env: REnvironmentInformation, graph?: DataflowGraph, map?: AstIdMap) => Value;
55
60
  declare function defaultBuiltInProcessor<OtherInfo>(name: RSymbol<OtherInfo & ParentInformation>, args: readonly RFunctionArgument<OtherInfo & ParentInformation>[], rootId: NodeId, data: DataflowProcessorInformation<OtherInfo & ParentInformation>, config: DefaultBuiltInProcessorConfiguration): DataflowInformation;
56
61
  export declare function registerBuiltInFunctions<Config extends object, Proc extends BuiltInIdentifierProcessorWithConfig<Config>>(both: boolean, names: readonly Identifier[], processor: Proc, config: Config): void;
57
62
  export declare const BuiltInProcessorMapper: {
@@ -77,6 +82,10 @@ export declare const BuiltInProcessorMapper: {
77
82
  readonly 'builtin:list': typeof processList;
78
83
  readonly 'builtin:vector': typeof processVector;
79
84
  };
85
+ export declare const BuiltInEvalHandlerMapper: {
86
+ readonly 'built-in:c': typeof resolveAsVector;
87
+ readonly 'builtin:vector': typeof resolveAsVector;
88
+ };
80
89
  export type BuiltInMappingName = keyof typeof BuiltInProcessorMapper;
81
90
  export type ConfigOfBuiltInMappingName<N extends BuiltInMappingName> = Parameters<typeof BuiltInProcessorMapper[N]>[4];
82
91
  export declare const BuiltInMemory: Map<Identifier, IdentifierDefinition[]>;