@eagleoutice/flowr 2.2.14 → 2.2.16

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 (245) hide show
  1. package/README.md +210 -6
  2. package/benchmark/slicer.d.ts +3 -1
  3. package/benchmark/slicer.js +8 -5
  4. package/benchmark/summarizer/first-phase/process.d.ts +2 -1
  5. package/benchmark/summarizer/first-phase/process.js +2 -2
  6. package/cli/benchmark-app.d.ts +1 -0
  7. package/cli/benchmark-app.js +4 -1
  8. package/cli/benchmark-helper-app.d.ts +1 -0
  9. package/cli/benchmark-helper-app.js +7 -8
  10. package/cli/common/options.js +2 -0
  11. package/cli/export-quads-app.js +2 -1
  12. package/cli/flowr.js +58 -57
  13. package/cli/repl/commands/repl-cfg.js +13 -13
  14. package/cli/repl/commands/repl-commands.js +3 -3
  15. package/cli/repl/commands/repl-dataflow.js +10 -10
  16. package/cli/repl/commands/repl-execute.d.ts +2 -3
  17. package/cli/repl/commands/repl-execute.js +5 -4
  18. package/cli/repl/commands/repl-lineage.js +4 -4
  19. package/cli/repl/commands/repl-main.d.ts +12 -1
  20. package/cli/repl/commands/repl-normalize.js +6 -6
  21. package/cli/repl/commands/repl-parse.js +2 -2
  22. package/cli/repl/commands/repl-query.js +9 -9
  23. package/cli/repl/commands/repl-version.js +1 -1
  24. package/cli/repl/core.d.ts +5 -2
  25. package/cli/repl/core.js +10 -8
  26. package/cli/repl/server/connection.d.ts +3 -1
  27. package/cli/repl/server/connection.js +7 -5
  28. package/cli/repl/server/server.d.ts +3 -2
  29. package/cli/repl/server/server.js +4 -2
  30. package/cli/script-core/statistics-core.d.ts +2 -1
  31. package/cli/script-core/statistics-core.js +2 -2
  32. package/cli/script-core/statistics-helper-core.d.ts +2 -1
  33. package/cli/script-core/statistics-helper-core.js +5 -4
  34. package/cli/slicer-app.js +4 -2
  35. package/cli/statistics-app.js +2 -1
  36. package/cli/statistics-helper-app.js +2 -1
  37. package/config.d.ts +12 -10
  38. package/config.js +27 -43
  39. package/control-flow/basic-cfg-guided-visitor.d.ts +3 -3
  40. package/control-flow/cfg-dead-code.d.ts +4 -0
  41. package/control-flow/cfg-dead-code.js +124 -0
  42. package/control-flow/cfg-simplification.d.ts +19 -6
  43. package/control-flow/cfg-simplification.js +23 -19
  44. package/control-flow/control-flow-graph.d.ts +3 -1
  45. package/control-flow/control-flow-graph.js +5 -0
  46. package/control-flow/dfg-cfg-guided-visitor.d.ts +9 -7
  47. package/control-flow/dfg-cfg-guided-visitor.js +16 -5
  48. package/control-flow/extract-cfg.d.ts +4 -2
  49. package/control-flow/extract-cfg.js +63 -59
  50. package/control-flow/semantic-cfg-guided-visitor.d.ts +36 -9
  51. package/control-flow/semantic-cfg-guided-visitor.js +73 -20
  52. package/control-flow/simple-visitor.d.ts +4 -0
  53. package/control-flow/simple-visitor.js +14 -0
  54. package/control-flow/syntax-cfg-guided-visitor.d.ts +2 -2
  55. package/core/pipeline-executor.d.ts +4 -1
  56. package/core/pipeline-executor.js +6 -5
  57. package/core/steps/all/core/10-normalize.d.ts +2 -0
  58. package/core/steps/all/core/10-normalize.js +1 -1
  59. package/core/steps/all/core/11-normalize-tree-sitter.d.ts +2 -1
  60. package/core/steps/all/core/11-normalize-tree-sitter.js +2 -2
  61. package/core/steps/all/core/20-dataflow.d.ts +2 -1
  62. package/core/steps/all/core/20-dataflow.js +2 -2
  63. package/core/steps/all/static-slicing/00-slice.d.ts +2 -1
  64. package/core/steps/all/static-slicing/00-slice.js +2 -2
  65. package/core/steps/pipeline/default-pipelines.d.ts +32 -31
  66. package/core/steps/pipeline/default-pipelines.js +8 -8
  67. package/core/steps/pipeline-step.d.ts +2 -1
  68. package/dataflow/environments/built-in-config.d.ts +4 -3
  69. package/dataflow/environments/built-in.d.ts +16 -1
  70. package/dataflow/environments/built-in.js +11 -5
  71. package/dataflow/environments/default-builtin-config.js +5 -3
  72. package/dataflow/environments/define.d.ts +2 -1
  73. package/dataflow/environments/define.js +4 -5
  74. package/dataflow/environments/remove.d.ts +6 -0
  75. package/dataflow/environments/remove.js +29 -0
  76. package/dataflow/environments/resolve-by-name.d.ts +0 -36
  77. package/dataflow/environments/resolve-by-name.js +0 -240
  78. package/dataflow/eval/resolve/alias-tracking.d.ts +92 -0
  79. package/dataflow/eval/resolve/alias-tracking.js +352 -0
  80. package/dataflow/eval/resolve/resolve-argument.d.ts +8 -0
  81. package/dataflow/eval/resolve/resolve-argument.js +118 -0
  82. package/dataflow/eval/resolve/resolve.d.ts +37 -0
  83. package/dataflow/eval/resolve/resolve.js +95 -0
  84. package/dataflow/eval/values/general.d.ts +27 -0
  85. package/dataflow/eval/values/general.js +73 -0
  86. package/dataflow/eval/values/intervals/interval-constants.d.ts +4 -0
  87. package/dataflow/eval/values/intervals/interval-constants.js +27 -0
  88. package/dataflow/eval/values/logical/logical-constants.d.ts +7 -0
  89. package/dataflow/eval/values/logical/logical-constants.js +31 -0
  90. package/dataflow/eval/values/r-value.d.ts +58 -0
  91. package/dataflow/eval/values/r-value.js +90 -0
  92. package/dataflow/eval/values/scalar/scalar-consatnts.d.ts +15 -0
  93. package/dataflow/eval/values/scalar/scalar-consatnts.js +35 -0
  94. package/dataflow/eval/values/sets/set-constants.d.ts +7 -0
  95. package/dataflow/eval/values/sets/set-constants.js +34 -0
  96. package/dataflow/eval/values/string/string-constants.d.ts +8 -0
  97. package/dataflow/eval/values/string/string-constants.js +45 -0
  98. package/dataflow/eval/values/vectors/vector-constants.d.ts +14 -0
  99. package/dataflow/eval/values/vectors/vector-constants.js +35 -0
  100. package/dataflow/extractor.d.ts +2 -1
  101. package/dataflow/extractor.js +2 -1
  102. package/dataflow/graph/unknown-replacement.d.ts +11 -0
  103. package/dataflow/graph/unknown-replacement.js +12 -0
  104. package/dataflow/graph/unknown-side-effect.d.ts +7 -0
  105. package/dataflow/graph/unknown-side-effect.js +13 -0
  106. package/dataflow/internal/process/functions/call/built-in/built-in-access.js +5 -6
  107. package/dataflow/internal/process/functions/call/built-in/built-in-apply.js +8 -5
  108. package/dataflow/internal/process/functions/call/built-in/built-in-assignment.d.ts +4 -2
  109. package/dataflow/internal/process/functions/call/built-in/built-in-assignment.js +15 -13
  110. package/dataflow/internal/process/functions/call/built-in/built-in-eval.js +20 -18
  111. package/dataflow/internal/process/functions/call/built-in/built-in-expression-list.js +7 -2
  112. package/dataflow/internal/process/functions/call/built-in/built-in-for-loop.js +2 -3
  113. package/dataflow/internal/process/functions/call/built-in/built-in-if-then-else.js +5 -4
  114. package/dataflow/internal/process/functions/call/built-in/built-in-list.js +2 -2
  115. package/dataflow/internal/process/functions/call/built-in/built-in-replacement.js +11 -5
  116. package/dataflow/internal/process/functions/call/built-in/built-in-source.d.ts +5 -3
  117. package/dataflow/internal/process/functions/call/built-in/built-in-source.js +26 -29
  118. package/dataflow/internal/process/functions/call/built-in/built-in-vector.js +2 -2
  119. package/dataflow/internal/process/functions/call/built-in/built-in-while-loop.js +23 -0
  120. package/dataflow/internal/process/functions/call/common.js +1 -1
  121. package/dataflow/internal/process/functions/call/known-call-handling.js +2 -1
  122. package/dataflow/internal/process/functions/process-parameter.js +1 -1
  123. package/dataflow/origin/dfg-get-symbol-refs.d.ts +21 -0
  124. package/dataflow/origin/dfg-get-symbol-refs.js +50 -0
  125. package/dataflow/processor.d.ts +5 -0
  126. package/documentation/doc-util/doc-cfg.js +4 -3
  127. package/documentation/doc-util/doc-code.d.ts +1 -1
  128. package/documentation/doc-util/doc-dfg.js +3 -2
  129. package/documentation/doc-util/doc-functions.d.ts +24 -0
  130. package/documentation/doc-util/doc-functions.js +65 -0
  131. package/documentation/doc-util/doc-normalized-ast.js +3 -2
  132. package/documentation/doc-util/doc-print.d.ts +5 -0
  133. package/documentation/doc-util/doc-print.js +36 -0
  134. package/documentation/doc-util/doc-query.d.ts +6 -3
  135. package/documentation/doc-util/doc-query.js +6 -3
  136. package/documentation/doc-util/doc-repl.js +2 -1
  137. package/documentation/doc-util/doc-search.js +3 -2
  138. package/documentation/doc-util/doc-types.d.ts +28 -6
  139. package/documentation/doc-util/doc-types.js +89 -45
  140. package/documentation/print-cfg-wiki.js +10 -11
  141. package/documentation/print-core-wiki.js +5 -5
  142. package/documentation/print-dataflow-graph-wiki.js +14 -13
  143. package/documentation/print-engines-wiki.js +2 -3
  144. package/documentation/print-faq-wiki.js +8 -2
  145. package/documentation/print-interface-wiki.js +1 -2
  146. package/documentation/print-linter-issue.d.ts +1 -0
  147. package/documentation/print-linter-issue.js +71 -0
  148. package/documentation/print-linter-wiki.js +219 -34
  149. package/documentation/print-linting-and-testing-wiki.js +2 -4
  150. package/documentation/print-normalized-ast-wiki.js +3 -3
  151. package/documentation/print-query-wiki.js +81 -2
  152. package/documentation/print-readme.js +24 -1
  153. package/documentation/print-search-wiki.js +1 -2
  154. package/linter/linter-executor.d.ts +3 -1
  155. package/linter/linter-executor.js +3 -2
  156. package/linter/linter-format.d.ts +67 -7
  157. package/linter/linter-format.js +12 -1
  158. package/linter/linter-rules.d.ts +155 -16
  159. package/linter/linter-rules.js +12 -4
  160. package/linter/linter-tags.d.ts +80 -0
  161. package/linter/linter-tags.js +85 -0
  162. package/linter/rules/absolute-path.d.ts +71 -0
  163. package/linter/rules/absolute-path.js +177 -0
  164. package/linter/rules/deprecated-functions.d.ts +43 -0
  165. package/linter/rules/deprecated-functions.js +58 -0
  166. package/linter/rules/{2-file-path-validity.d.ts → file-path-validity.d.ts} +16 -6
  167. package/linter/rules/{2-file-path-validity.js → file-path-validity.js} +21 -13
  168. package/linter/rules/naming-convention.d.ts +71 -0
  169. package/linter/rules/naming-convention.js +164 -0
  170. package/linter/rules/seeded-randomness.d.ts +65 -0
  171. package/linter/rules/seeded-randomness.js +122 -0
  172. package/linter/rules/unused-definition.d.ts +41 -0
  173. package/linter/rules/unused-definition.js +105 -0
  174. package/package.json +4 -1
  175. package/queries/base-query-format.d.ts +2 -0
  176. package/queries/catalog/call-context-query/call-context-query-executor.d.ts +1 -1
  177. package/queries/catalog/call-context-query/call-context-query-executor.js +2 -2
  178. package/queries/catalog/cluster-query/cluster-query-format.d.ts +1 -1
  179. package/queries/catalog/config-query/config-query-executor.d.ts +1 -1
  180. package/queries/catalog/config-query/config-query-executor.js +2 -3
  181. package/queries/catalog/control-flow-query/control-flow-query-executor.d.ts +3 -0
  182. package/queries/catalog/control-flow-query/control-flow-query-executor.js +20 -0
  183. package/queries/catalog/control-flow-query/control-flow-query-format.d.ts +81 -0
  184. package/queries/catalog/control-flow-query/control-flow-query-format.js +34 -0
  185. package/queries/catalog/dataflow-lens-query/dataflow-lens-query-format.d.ts +1 -1
  186. package/queries/catalog/dataflow-query/dataflow-query-format.d.ts +1 -1
  187. package/queries/catalog/dependencies-query/dependencies-query-executor.js +4 -115
  188. package/queries/catalog/dependencies-query/dependencies-query-format.d.ts +1 -1
  189. package/queries/catalog/happens-before-query/happens-before-query-format.d.ts +1 -1
  190. package/queries/catalog/id-map-query/id-map-query-format.d.ts +1 -1
  191. package/queries/catalog/lineage-query/lineage-query-format.d.ts +1 -1
  192. package/queries/catalog/linter-query/linter-query-executor.d.ts +1 -1
  193. package/queries/catalog/linter-query/linter-query-executor.js +2 -2
  194. package/queries/catalog/linter-query/linter-query-format.d.ts +1 -1
  195. package/queries/catalog/linter-query/linter-query-format.js +17 -12
  196. package/queries/catalog/normalized-ast-query/normalized-ast-query-format.d.ts +1 -1
  197. package/queries/catalog/origin-query/origin-query-format.d.ts +1 -1
  198. package/queries/catalog/project-query/project-query-format.d.ts +1 -1
  199. package/queries/catalog/resolve-value-query/resolve-value-query-executor.d.ts +1 -1
  200. package/queries/catalog/resolve-value-query/resolve-value-query-executor.js +4 -4
  201. package/queries/catalog/resolve-value-query/resolve-value-query-format.d.ts +3 -2
  202. package/queries/catalog/resolve-value-query/resolve-value-query-format.js +2 -22
  203. package/queries/catalog/search-query/search-query-executor.d.ts +1 -1
  204. package/queries/catalog/search-query/search-query-executor.js +2 -2
  205. package/queries/catalog/search-query/search-query-format.d.ts +1 -1
  206. package/queries/catalog/static-slice-query/static-slice-query-executor.d.ts +1 -1
  207. package/queries/catalog/static-slice-query/static-slice-query-executor.js +2 -2
  208. package/queries/catalog/static-slice-query/static-slice-query-format.d.ts +1 -1
  209. package/queries/query.d.ts +75 -15
  210. package/queries/query.js +2 -0
  211. package/r-bridge/lang-4.x/ast/parser/json/parser.d.ts +2 -1
  212. package/r-bridge/lang-4.x/ast/parser/json/parser.js +4 -2
  213. package/r-bridge/lang-4.x/convert-values.js +2 -1
  214. package/r-bridge/lang-4.x/tree-sitter/tree-sitter-executor.d.ts +3 -1
  215. package/r-bridge/lang-4.x/tree-sitter/tree-sitter-executor.js +4 -4
  216. package/r-bridge/lang-4.x/tree-sitter/tree-sitter-normalize.d.ts +1 -1
  217. package/r-bridge/lang-4.x/tree-sitter/tree-sitter-normalize.js +18 -9
  218. package/r-bridge/shell.d.ts +3 -2
  219. package/r-bridge/shell.js +4 -5
  220. package/search/flowr-search-builder.d.ts +6 -2
  221. package/search/flowr-search-builder.js +7 -0
  222. package/search/flowr-search-filters.d.ts +32 -8
  223. package/search/flowr-search-filters.js +42 -15
  224. package/search/flowr-search.d.ts +4 -0
  225. package/search/search-executor/search-enrichers.d.ts +7 -3
  226. package/search/search-executor/search-enrichers.js +32 -20
  227. package/search/search-executor/search-generators.js +1 -1
  228. package/search/search-executor/search-transformer.d.ts +2 -0
  229. package/search/search-executor/search-transformer.js +10 -1
  230. package/slicing/criterion/parse.d.ts +8 -0
  231. package/slicing/criterion/parse.js +20 -0
  232. package/slicing/static/static-slicer.d.ts +1 -1
  233. package/slicing/static/static-slicer.js +2 -3
  234. package/statistics/statistics.d.ts +3 -1
  235. package/statistics/statistics.js +5 -4
  236. package/util/containers.d.ts +12 -9
  237. package/util/containers.js +12 -9
  238. package/util/objects.d.ts +5 -4
  239. package/util/range.d.ts +5 -1
  240. package/util/range.js +11 -3
  241. package/util/text/strings.d.ts +6 -0
  242. package/util/text/strings.js +35 -0
  243. package/util/version.js +1 -1
  244. package/linter/rules/1-deprecated-functions.d.ts +0 -34
  245. package/linter/rules/1-deprecated-functions.js +0 -54
@@ -1,11 +1,13 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.DefaultCfgSimplificationOrder = void 0;
3
+ exports.DefaultCfgSimplificationOrder = exports.CfgSimplificationPasses = void 0;
4
4
  exports.simplifyControlFlowInformation = simplifyControlFlowInformation;
5
- const simple_visitor_1 = require("./simple-visitor");
6
5
  const cfg_to_basic_blocks_1 = require("./cfg-to-basic-blocks");
7
- const CfgSimplificationPasses = {
6
+ const simple_visitor_1 = require("./simple-visitor");
7
+ const cfg_dead_code_1 = require("./cfg-dead-code");
8
+ exports.CfgSimplificationPasses = {
8
9
  'unique-cf-sets': uniqueControlFlowSets,
10
+ 'analyze-dead-code': cfg_dead_code_1.cfgAnalyzeDeadCode,
9
11
  'remove-dead-code': cfgRemoveDeadCode,
10
12
  'to-basic-blocks': toBasicBlocks
11
13
  };
@@ -18,25 +20,17 @@ exports.DefaultCfgSimplificationOrder = [
18
20
  * Simplify the control flow information by applying the given passes.
19
21
  * This may reduce the vertex count, in- and outgoing edges, entry and exit points, etc.
20
22
  */
21
- function simplifyControlFlowInformation(cfg, passes = exports.DefaultCfgSimplificationOrder) {
23
+ function simplifyControlFlowInformation(cfg, info, passes = exports.DefaultCfgSimplificationOrder) {
22
24
  for (const pass of passes) {
23
- const passFn = CfgSimplificationPasses[pass];
24
- cfg = passFn(cfg);
25
+ const passFn = exports.CfgSimplificationPasses[pass];
26
+ cfg = passFn(cfg, info);
25
27
  }
26
28
  return cfg;
27
29
  }
28
- function uniqueControlFlowSets(cfg) {
29
- return {
30
- returns: [...new Set(cfg.returns)],
31
- entryPoints: [...new Set(cfg.entryPoints)],
32
- exitPoints: [...new Set(cfg.exitPoints)],
33
- breaks: [...new Set(cfg.breaks)],
34
- nexts: [...new Set(cfg.nexts)],
35
- graph: cfg.graph
36
- };
37
- }
38
- /* currently this does not do work on function definitions */
39
- function cfgRemoveDeadCode(cfg) {
30
+ /**
31
+ * removes dead vertices and edges from the control flow graph.
32
+ */
33
+ function cfgRemoveDeadCode(cfg, _info) {
40
34
  // remove every root level node and accompanying vertices that can not be reached from the entry points
41
35
  const reachable = new Set();
42
36
  (0, simple_visitor_1.visitCfgInOrder)(cfg.graph, cfg.entryPoints, node => {
@@ -49,7 +43,17 @@ function cfgRemoveDeadCode(cfg) {
49
43
  }
50
44
  return cfg;
51
45
  }
52
- function toBasicBlocks(cfg) {
46
+ function uniqueControlFlowSets(cfg, _info) {
47
+ return {
48
+ returns: [...new Set(cfg.returns)],
49
+ entryPoints: [...new Set(cfg.entryPoints)],
50
+ exitPoints: [...new Set(cfg.exitPoints)],
51
+ breaks: [...new Set(cfg.breaks)],
52
+ nexts: [...new Set(cfg.nexts)],
53
+ graph: cfg.graph
54
+ };
55
+ }
56
+ function toBasicBlocks(cfg, _info) {
53
57
  return (0, cfg_to_basic_blocks_1.convertCfgToBasicBlocks)(cfg);
54
58
  }
55
59
  //# sourceMappingURL=cfg-simplification.js.map
@@ -67,10 +67,11 @@ export interface CfgBasicBlockVertex extends CfgBaseVertex {
67
67
  */
68
68
  export type CfgSimpleVertex = CfgStatementVertex | CfgExpressionVertex | CfgBasicBlockVertex | CfgMidMarkerVertex | CfgEndMarkerVertex;
69
69
  export declare function equalVertex(a: CfgSimpleVertex, b: CfgSimpleVertex): boolean;
70
+ export declare function isMarkerVertex(vertex: CfgSimpleVertex): vertex is CfgMidMarkerVertex | CfgEndMarkerVertex;
70
71
  interface CfgFlowDependencyEdge extends MergeableRecord {
71
72
  label: CfgEdgeType.Fd;
72
73
  }
73
- interface CfgControlDependencyEdge extends MergeableRecord {
74
+ export interface CfgControlDependencyEdge extends MergeableRecord {
74
75
  label: CfgEdgeType.Cd;
75
76
  /** the id which caused the control dependency */
76
77
  caused: NodeId;
@@ -166,6 +167,7 @@ export interface ReadOnlyControlFlowGraph {
166
167
  */
167
168
  export declare class ControlFlowGraph<Vertex extends CfgSimpleVertex = CfgSimpleVertex> implements ReadOnlyControlFlowGraph {
168
169
  private readonly rootVertices;
170
+ /** Nesting-Independent vertex information, mapping the id to the vertex */
169
171
  private readonly vertexInformation;
170
172
  /** the basic block children map contains a mapping of ids to all vertices that are nested in basic blocks, mapping them to the Id of the block they appear in */
171
173
  private readonly bbChildren;
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ControlFlowGraph = exports.CfgVertexType = void 0;
4
4
  exports.edgeTypeToString = edgeTypeToString;
5
5
  exports.equalVertex = equalVertex;
6
+ exports.isMarkerVertex = isMarkerVertex;
6
7
  exports.emptyControlFlowInformation = emptyControlFlowInformation;
7
8
  const assert_1 = require("../util/assert");
8
9
  var CfgVertexType;
@@ -43,6 +44,9 @@ function equalVertex(a, b) {
43
44
  }
44
45
  return true;
45
46
  }
47
+ function isMarkerVertex(vertex) {
48
+ return vertex.type === CfgVertexType.MidMarker || vertex.type === CfgVertexType.EndMarker;
49
+ }
46
50
  /**
47
51
  * This class represents the control flow graph of an R program.
48
52
  * The control flow may be hierarchical when confronted with function definitions (see {@link CfgSimpleVertex} and {@link CFG#rootVertexIds|rootVertexIds()}).
@@ -55,6 +59,7 @@ function equalVertex(a, b) {
55
59
  */
56
60
  class ControlFlowGraph {
57
61
  rootVertices = new Set();
62
+ /** Nesting-Independent vertex information, mapping the id to the vertex */
58
63
  vertexInformation = new Map();
59
64
  /** the basic block children map contains a mapping of ids to all vertices that are nested in basic blocks, mapping them to the Id of the block they appear in */
60
65
  bbChildren = new Map();
@@ -1,29 +1,31 @@
1
- import type { CfgExpressionVertex, CfgStatementVertex, ControlFlowInformation } from './control-flow-graph';
1
+ import { type CfgBasicBlockVertex, type CfgEndMarkerVertex, type CfgExpressionVertex, type CfgSimpleVertex, type CfgStatementVertex, type ControlFlowInformation } from './control-flow-graph';
2
2
  import type { NodeId } from '../r-bridge/lang-4.x/ast/model/processing/node-id';
3
- import type { DataflowInformation } from '../dataflow/info';
4
3
  import type { DataflowGraphVertexArgument, DataflowGraphVertexFunctionCall, DataflowGraphVertexFunctionDefinition, DataflowGraphVertexUse, DataflowGraphVertexValue, DataflowGraphVertexVariableDefinition } from '../dataflow/graph/vertex';
5
4
  import type { BasicCfgGuidedVisitorConfiguration } from './basic-cfg-guided-visitor';
6
5
  import { BasicCfgGuidedVisitor } from './basic-cfg-guided-visitor';
7
- export interface DataflowCfgGuidedVisitorConfiguration<Cfg extends ControlFlowInformation = ControlFlowInformation, Dfg extends DataflowInformation = DataflowInformation> extends BasicCfgGuidedVisitorConfiguration<Cfg> {
8
- readonly dataflow: Dfg;
6
+ import type { DataflowGraph } from '../dataflow/graph/graph';
7
+ export interface DataflowCfgGuidedVisitorConfiguration<ControlFlow extends ControlFlowInformation = ControlFlowInformation, Dfg extends DataflowGraph = DataflowGraph> extends BasicCfgGuidedVisitorConfiguration<ControlFlow> {
8
+ readonly dfg: Dfg;
9
+ readonly defaultVisitingType?: 'entry' | 'exit';
9
10
  }
10
11
  /**
11
12
  * This visitor extends on the {@link BasicCfgGuidedVisitor} by dispatching visitors based on the dataflow graph.
12
13
  *
13
14
  * Use {@link BasicCfgGuidedVisitor#start} to start the traversal.
14
15
  */
15
- export declare class DataflowAwareCfgGuidedVisitor<Cfg extends ControlFlowInformation = ControlFlowInformation, Dfg extends DataflowInformation = DataflowInformation, Config extends DataflowCfgGuidedVisitorConfiguration<Cfg, Dfg> = DataflowCfgGuidedVisitorConfiguration<Cfg, Dfg>> extends BasicCfgGuidedVisitor<Cfg, Config> {
16
+ export declare class DataflowAwareCfgGuidedVisitor<ControlFlow extends ControlFlowInformation = ControlFlowInformation, Dfg extends DataflowGraph = DataflowGraph, Config extends DataflowCfgGuidedVisitorConfiguration<ControlFlow, Dfg> = DataflowCfgGuidedVisitorConfiguration<ControlFlow, Dfg>> extends BasicCfgGuidedVisitor<ControlFlow, Config> {
16
17
  /**
17
18
  * Get the dataflow graph vertex for the given id
18
19
  */
19
20
  protected getDataflowGraph(id: NodeId): DataflowGraphVertexArgument | undefined;
20
21
  protected onStatementNode(node: CfgStatementVertex): void;
21
22
  protected onExpressionNode(node: CfgExpressionVertex): void;
22
- private onExprOrStmtNode;
23
+ protected onEndMarkerNode(node: CfgEndMarkerVertex): void;
24
+ protected visitDataflowNode(node: Exclude<CfgSimpleVertex, CfgBasicBlockVertex>): void;
23
25
  /**
24
26
  * called for every cfg vertex that has no corresponding dataflow vertex.
25
27
  */
26
- protected visitUnknown(_vertex: CfgStatementVertex | CfgExpressionVertex): void;
28
+ protected visitUnknown(_vertex: Exclude<CfgSimpleVertex, CfgBasicBlockVertex>): void;
27
29
  protected visitValue(_val: DataflowGraphVertexValue): void;
28
30
  protected visitVariableUse(_use: DataflowGraphVertexUse): void;
29
31
  protected visitVariableDefinition(_def: DataflowGraphVertexVariableDefinition): void;
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.DataflowAwareCfgGuidedVisitor = void 0;
4
+ const control_flow_graph_1 = require("./control-flow-graph");
4
5
  const vertex_1 = require("../dataflow/graph/vertex");
5
6
  const basic_cfg_guided_visitor_1 = require("./basic-cfg-guided-visitor");
6
7
  const assert_1 = require("../util/assert");
@@ -14,18 +15,28 @@ class DataflowAwareCfgGuidedVisitor extends basic_cfg_guided_visitor_1.BasicCfgG
14
15
  * Get the dataflow graph vertex for the given id
15
16
  */
16
17
  getDataflowGraph(id) {
17
- return this.config.dataflow.graph.getVertex(id);
18
+ return this.config.dfg.getVertex(id);
18
19
  }
19
20
  onStatementNode(node) {
20
21
  super.onStatementNode(node);
21
- this.onExprOrStmtNode(node);
22
+ if (this.config.defaultVisitingType !== 'exit' || node.end === undefined) {
23
+ this.visitDataflowNode(node);
24
+ }
22
25
  }
23
26
  onExpressionNode(node) {
24
27
  super.onExpressionNode(node);
25
- this.onExprOrStmtNode(node);
28
+ if (this.config.defaultVisitingType !== 'exit' || node.end === undefined) {
29
+ this.visitDataflowNode(node);
30
+ }
31
+ }
32
+ onEndMarkerNode(node) {
33
+ super.onEndMarkerNode(node);
34
+ if (this.config.defaultVisitingType === 'exit') {
35
+ this.visitDataflowNode(node);
36
+ }
26
37
  }
27
- onExprOrStmtNode(node) {
28
- const dfgVertex = this.getDataflowGraph(node.id);
38
+ visitDataflowNode(node) {
39
+ const dfgVertex = this.getDataflowGraph((0, control_flow_graph_1.isMarkerVertex)(node) ? node.root : node.id);
29
40
  if (!dfgVertex) {
30
41
  this.visitUnknown(node);
31
42
  return;
@@ -3,18 +3,20 @@ import type { NormalizedAst, ParentInformation } from '../r-bridge/lang-4.x/ast/
3
3
  import type { DataflowGraph } from '../dataflow/graph/graph';
4
4
  import type { ControlFlowInformation } from './control-flow-graph';
5
5
  import type { CfgSimplificationPassName } from './cfg-simplification';
6
+ import type { FlowrConfigOptions } from '../config';
6
7
  /**
7
8
  * Given a normalized AST this approximates the control flow graph of the program.
8
- * This few is different from the computation of the dataflow graph and may differ,
9
+ * This view is different from the computation of the dataflow graph and may differ,
9
10
  * especially because it focuses on intra-procedural analysis.
10
11
  *
11
12
  * @param ast - the normalized AST
13
+ * @param config - the Flowr config
12
14
  * @param graph - additional dataflow facts to consider by the control flow extraction
13
15
  * @param simplifications - a list of simplification passes to apply to the control flow graph
14
16
  *
15
17
  * @see {@link extractSimpleCfg} - for a simplified version of this function
16
18
  */
17
- export declare function extractCfg<Info = ParentInformation>(ast: NormalizedAst<Info>, graph?: DataflowGraph, simplifications?: readonly CfgSimplificationPassName[]): ControlFlowInformation;
19
+ export declare function extractCfg<Info = ParentInformation>(ast: NormalizedAst<Info & ParentInformation>, config: FlowrConfigOptions, graph?: DataflowGraph, simplifications?: readonly CfgSimplificationPassName[]): ControlFlowInformation;
18
20
  /**
19
21
  * Simplified version of {@link extractCfg} that is much quicker, but much simpler!
20
22
  */
@@ -53,17 +53,18 @@ function dataflowCfgFolds(dataflowGraph) {
53
53
  }
54
54
  /**
55
55
  * Given a normalized AST this approximates the control flow graph of the program.
56
- * This few is different from the computation of the dataflow graph and may differ,
56
+ * This view is different from the computation of the dataflow graph and may differ,
57
57
  * especially because it focuses on intra-procedural analysis.
58
58
  *
59
59
  * @param ast - the normalized AST
60
+ * @param config - the Flowr config
60
61
  * @param graph - additional dataflow facts to consider by the control flow extraction
61
62
  * @param simplifications - a list of simplification passes to apply to the control flow graph
62
63
  *
63
64
  * @see {@link extractSimpleCfg} - for a simplified version of this function
64
65
  */
65
- function extractCfg(ast, graph, simplifications) {
66
- return (0, cfg_simplification_1.simplifyControlFlowInformation)((0, fold_1.foldAst)(ast.ast, graph ? dataflowCfgFolds(graph) : cfgFolds), simplifications);
66
+ function extractCfg(ast, config, graph, simplifications) {
67
+ return (0, cfg_simplification_1.simplifyControlFlowInformation)((0, fold_1.foldAst)(ast.ast, graph ? dataflowCfgFolds(graph) : cfgFolds), { ast, dfg: graph, config }, simplifications);
67
68
  }
68
69
  /**
69
70
  * Simplified version of {@link extractCfg} that is much quicker, but much simpler!
@@ -72,10 +73,8 @@ function extractSimpleCfg(ast) {
72
73
  return (0, fold_1.foldAst)(ast.ast, cfgFolds);
73
74
  }
74
75
  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] };
76
+ return ({ info: { id } }) => {
77
+ return { graph: new control_flow_graph_1.ControlFlowGraph().addVertex({ id, type }), breaks: [], nexts: [], returns: [], exitPoints: [id], entryPoints: [id] };
79
78
  };
80
79
  }
81
80
  function cfgBreak(leaf) {
@@ -91,40 +90,41 @@ function identifyMayStatementType(node) {
91
90
  return node.info.role === "expr-list-child" /* RoleInParent.ExpressionListChild */ ? control_flow_graph_1.CfgVertexType.Statement : control_flow_graph_1.CfgVertexType.Expression;
92
91
  }
93
92
  function cfgIfThenElse(ifNode, condition, then, otherwise) {
93
+ const ifId = ifNode.info.id;
94
94
  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 });
95
+ graph.addVertex({ id: ifId, type: identifyMayStatementType(ifNode), mid: [ifId + '-condition'], end: [ifId + '-exit'] });
96
+ graph.addVertex({ id: ifId + '-condition', kind: 'condition', type: control_flow_graph_1.CfgVertexType.MidMarker, root: ifId });
97
+ graph.addVertex({ id: ifId + '-exit', type: control_flow_graph_1.CfgVertexType.EndMarker, root: ifId });
98
98
  graph.mergeWith(condition.graph);
99
99
  graph.mergeWith(then.graph);
100
100
  if (otherwise) {
101
101
  graph.mergeWith(otherwise.graph);
102
102
  }
103
103
  for (const exitPoint of condition.exitPoints) {
104
- graph.addEdge(ifNode.info.id + '-condition', exitPoint, { label: 0 /* CfgEdgeType.Fd */ });
104
+ graph.addEdge(ifId + '-condition', exitPoint, { label: 0 /* CfgEdgeType.Fd */ });
105
105
  }
106
106
  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 });
107
+ graph.addEdge(entryPoint, ifId + '-condition', { label: 1 /* CfgEdgeType.Cd */, when: convert_values_1.RTrue, caused: ifId });
108
108
  }
109
109
  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 });
110
+ graph.addEdge(entryPoint, ifId + '-condition', { label: 1 /* CfgEdgeType.Cd */, when: convert_values_1.RFalse, caused: ifId });
111
111
  }
112
112
  for (const entryPoint of condition.entryPoints) {
113
- graph.addEdge(entryPoint, ifNode.info.id, { label: 0 /* CfgEdgeType.Fd */ });
113
+ graph.addEdge(entryPoint, ifId, { label: 0 /* CfgEdgeType.Fd */ });
114
114
  }
115
115
  for (const exit of [...then.exitPoints, ...otherwise?.exitPoints ?? []]) {
116
- graph.addEdge(ifNode.info.id + '-exit', exit, { label: 0 /* CfgEdgeType.Fd */ });
116
+ graph.addEdge(ifId + '-exit', exit, { label: 0 /* CfgEdgeType.Fd */ });
117
117
  }
118
118
  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 });
119
+ graph.addEdge(ifId + '-exit', ifId + '-condition', { label: 1 /* CfgEdgeType.Cd */, when: convert_values_1.RFalse, caused: ifId });
120
120
  }
121
121
  return {
122
122
  graph,
123
123
  breaks: [...then.breaks, ...otherwise?.breaks ?? []],
124
124
  nexts: [...then.nexts, ...otherwise?.nexts ?? []],
125
125
  returns: [...then.returns, ...otherwise?.returns ?? []],
126
- exitPoints: [ifNode.info.id + '-exit'],
127
- entryPoints: [ifNode.info.id]
126
+ exitPoints: [ifId + '-exit'],
127
+ entryPoints: [ifId]
128
128
  };
129
129
  }
130
130
  function cfgRepeat(repeat, body) {
@@ -144,110 +144,114 @@ function cfgRepeat(repeat, body) {
144
144
  return { graph, breaks: [], nexts: [], returns: body.returns, exitPoints: [repeat.info.id + '-exit'], entryPoints: [repeat.info.id] };
145
145
  }
146
146
  function cfgWhile(whileLoop, condition, body) {
147
+ const whileId = whileLoop.info.id;
147
148
  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 });
149
+ graph.addVertex({ id: whileId, type: identifyMayStatementType(whileLoop), mid: [whileId + '-condition'], end: [whileId + '-exit'] });
150
+ graph.addVertex({ id: whileId + '-condition', kind: 'condition', type: control_flow_graph_1.CfgVertexType.MidMarker, root: whileId });
151
+ graph.addVertex({ id: whileId + '-exit', type: control_flow_graph_1.CfgVertexType.EndMarker, root: whileId });
151
152
  graph.mergeWith(body.graph);
152
153
  for (const entry of condition.entryPoints) {
153
- graph.addEdge(entry, whileLoop.info.id, { label: 0 /* CfgEdgeType.Fd */ });
154
+ graph.addEdge(entry, whileId, { label: 0 /* CfgEdgeType.Fd */ });
154
155
  }
155
156
  for (const exit of condition.exitPoints) {
156
- graph.addEdge(whileLoop.info.id + '-condition', exit, { label: 0 /* CfgEdgeType.Fd */ });
157
+ graph.addEdge(whileId + '-condition', exit, { label: 0 /* CfgEdgeType.Fd */ });
157
158
  }
158
159
  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 });
160
+ graph.addEdge(entry, whileId + '-condition', { label: 1 /* CfgEdgeType.Cd */, when: convert_values_1.RTrue, caused: whileId });
160
161
  }
161
162
  for (const next of [...body.nexts, ...body.exitPoints]) {
162
- graph.addEdge(whileLoop.info.id, next, { label: 0 /* CfgEdgeType.Fd */ });
163
+ graph.addEdge(whileId, next, { label: 0 /* CfgEdgeType.Fd */ });
163
164
  }
164
165
  for (const breakPoint of body.breaks) {
165
- graph.addEdge(whileLoop.info.id + '-exit', breakPoint, { label: 0 /* CfgEdgeType.Fd */ });
166
+ graph.addEdge(whileId + '-exit', breakPoint, { label: 0 /* CfgEdgeType.Fd */ });
166
167
  }
167
168
  // 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] };
169
+ graph.addEdge(whileId + '-exit', whileId + '-condition', { label: 1 /* CfgEdgeType.Cd */, when: convert_values_1.RFalse, caused: whileId });
170
+ return { graph, breaks: [], nexts: [], returns: body.returns, exitPoints: [whileId + '-exit'], entryPoints: [whileId] };
170
171
  }
171
172
  function cfgFor(forLoop, variable, vector, body) {
173
+ const forLoopId = forLoop.info.id;
172
174
  const graph = variable.graph;
173
- graph.addVertex({ id: forLoop.info.id, type: identifyMayStatementType(forLoop), end: [forLoop.info.id + '-exit'], mid: [forLoop.info.id + '-head'] });
175
+ graph.addVertex({ id: forLoopId, type: identifyMayStatementType(forLoop), end: [forLoopId + '-exit'], mid: [forLoopId + '-head'] });
174
176
  graph.mergeWith(vector.graph);
175
177
  graph.mergeWith(body.graph);
176
178
  for (const entry of vector.entryPoints) {
177
- graph.addEdge(entry, forLoop.info.id, { label: 0 /* CfgEdgeType.Fd */ });
179
+ graph.addEdge(entry, forLoopId, { label: 0 /* CfgEdgeType.Fd */ });
178
180
  }
179
181
  for (const exit of vector.exitPoints) {
180
182
  for (const entry of variable.entryPoints) {
181
183
  graph.addEdge(entry, exit, { label: 0 /* CfgEdgeType.Fd */ });
182
184
  }
183
185
  }
184
- graph.addVertex({ id: forLoop.info.id + '-head', type: control_flow_graph_1.CfgVertexType.MidMarker, root: forLoop.info.id, kind: 'head' });
186
+ graph.addVertex({ id: forLoopId + '-head', type: control_flow_graph_1.CfgVertexType.MidMarker, root: forLoopId, kind: 'head' });
185
187
  for (const exit of variable.exitPoints) {
186
- graph.addEdge(forLoop.info.id + '-head', exit, { label: 0 /* CfgEdgeType.Fd */ });
188
+ graph.addEdge(forLoopId + '-head', exit, { label: 0 /* CfgEdgeType.Fd */ });
187
189
  }
188
190
  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 });
191
+ graph.addEdge(entry, forLoopId + '-head', { label: 1 /* CfgEdgeType.Cd */, when: convert_values_1.RTrue, caused: forLoopId });
190
192
  }
191
193
  for (const next of [...body.nexts, ...body.exitPoints]) {
192
- graph.addEdge(forLoop.info.id, next, { label: 0 /* CfgEdgeType.Fd */ });
194
+ graph.addEdge(forLoopId, next, { label: 0 /* CfgEdgeType.Fd */ });
193
195
  }
194
196
  for (const breakPoint of body.breaks) {
195
- graph.addEdge(forLoop.info.id + '-exit', breakPoint, { label: 0 /* CfgEdgeType.Fd */ });
197
+ graph.addEdge(forLoopId + '-exit', breakPoint, { label: 0 /* CfgEdgeType.Fd */ });
196
198
  }
197
199
  const isNotEndless = body.exitPoints.length > 0 || body.breaks.length > 0;
198
200
  if (isNotEndless) {
199
201
  graph.addVertex({
200
- id: forLoop.info.id + '-exit',
202
+ id: forLoopId + '-exit',
201
203
  type: control_flow_graph_1.CfgVertexType.EndMarker,
202
- root: forLoop.info.id
204
+ root: forLoopId
203
205
  });
204
- graph.addEdge(forLoop.info.id + '-exit', forLoop.info.id + '-head', { label: 1 /* CfgEdgeType.Cd */, when: convert_values_1.RFalse, caused: forLoop.info.id });
206
+ graph.addEdge(forLoopId + '-exit', forLoopId + '-head', { label: 1 /* CfgEdgeType.Cd */, when: convert_values_1.RFalse, caused: forLoopId });
205
207
  }
206
- return { graph, breaks: [], nexts: [], returns: body.returns, exitPoints: isNotEndless ? [forLoop.info.id + '-exit'] : [], entryPoints: [forLoop.info.id] };
208
+ return { graph, breaks: [], nexts: [], returns: body.returns, exitPoints: isNotEndless ? [forLoopId + '-exit'] : [], entryPoints: [forLoopId] };
207
209
  }
208
210
  function cfgFunctionDefinition(fn, params, body) {
211
+ const fnId = fn.info.id;
209
212
  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'] });
213
+ const children = [fnId + '-params', fnId + '-exit'];
214
+ graph.addVertex({ id: fnId + '-params', kind: 'parameters', type: control_flow_graph_1.CfgVertexType.MidMarker, root: fnId }, false);
215
+ graph.addVertex({ id: fnId + '-exit', type: control_flow_graph_1.CfgVertexType.EndMarker, root: fnId }, false);
216
+ graph.addVertex({ id: fnId, children, type: identifyMayStatementType(fn), mid: [fnId + '-params'], end: [fnId + '-exit'] });
214
217
  graph.mergeWith(body.graph, true);
215
218
  children.push(...body.graph.rootIds());
216
219
  for (const param of params) {
217
220
  graph.mergeWith(param.graph, true);
218
221
  children.push(...param.graph.rootIds());
219
222
  for (const entry of param.entryPoints) {
220
- graph.addEdge(entry, fn.info.id, { label: 0 /* CfgEdgeType.Fd */ });
223
+ graph.addEdge(entry, fnId, { label: 0 /* CfgEdgeType.Fd */ });
221
224
  }
222
225
  for (const exit of param.exitPoints) {
223
- graph.addEdge(fn.info.id + '-params', exit, { label: 0 /* CfgEdgeType.Fd */ });
226
+ graph.addEdge(fnId + '-params', exit, { label: 0 /* CfgEdgeType.Fd */ });
224
227
  }
225
228
  }
226
229
  if (params.length === 0) {
227
- graph.addEdge(fn.info.id + '-params', fn.info.id, { label: 0 /* CfgEdgeType.Fd */ });
230
+ graph.addEdge(fnId + '-params', fnId, { label: 0 /* CfgEdgeType.Fd */ });
228
231
  }
229
232
  for (const entry of body.entryPoints) {
230
- graph.addEdge(entry, fn.info.id + '-params', { label: 0 /* CfgEdgeType.Fd */ });
233
+ graph.addEdge(entry, fnId + '-params', { label: 0 /* CfgEdgeType.Fd */ });
231
234
  }
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 */ });
235
+ // breaks and nexts should be illegal but safe is safe, I guess
236
+ for (const next of body.returns.concat(body.breaks, body.nexts, body.exitPoints)) {
237
+ graph.addEdge(fnId + '-exit', next, { label: 0 /* CfgEdgeType.Fd */ });
235
238
  }
236
- return { graph: graph, breaks: [], nexts: [], returns: [], exitPoints: [fn.info.id], entryPoints: [fn.info.id] };
239
+ return { graph: graph, breaks: [], nexts: [], returns: [], exitPoints: [fnId], entryPoints: [fnId] };
237
240
  }
238
241
  function cfgFunctionCall(call, name, args, exit = 'exit') {
242
+ const callId = call.info.id;
239
243
  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] });
244
+ const info = { graph, breaks: [...name.breaks], nexts: [...name.nexts], returns: [...name.returns], exitPoints: [callId + '-' + exit], entryPoints: [callId] };
245
+ graph.addVertex({ id: callId, type: identifyMayStatementType(call), mid: [callId + '-name'], end: [callId + '-' + exit] });
242
246
  for (const entryPoint of name.entryPoints) {
243
- graph.addEdge(entryPoint, call.info.id, { label: 0 /* CfgEdgeType.Fd */ });
247
+ graph.addEdge(entryPoint, callId, { label: 0 /* CfgEdgeType.Fd */ });
244
248
  }
245
- graph.addVertex({ id: call.info.id + '-name', kind: 'name', type: control_flow_graph_1.CfgVertexType.MidMarker, root: call.info.id });
249
+ graph.addVertex({ id: callId + '-name', kind: 'name', type: control_flow_graph_1.CfgVertexType.MidMarker, root: callId });
246
250
  for (const exitPoint of name.exitPoints) {
247
- graph.addEdge(call.info.id + '-name', exitPoint, { label: 0 /* CfgEdgeType.Fd */ });
251
+ graph.addEdge(callId + '-name', exitPoint, { label: 0 /* CfgEdgeType.Fd */ });
248
252
  }
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'];
253
+ graph.addVertex({ id: callId + '-' + exit, type: control_flow_graph_1.CfgVertexType.EndMarker, root: callId });
254
+ let lastArgExits = [callId + '-name'];
251
255
  for (const arg of args) {
252
256
  if (arg === r_function_call_1.EmptyArgument) {
253
257
  continue;
@@ -264,7 +268,7 @@ function cfgFunctionCall(call, name, args, exit = 'exit') {
264
268
  lastArgExits = arg.exitPoints;
265
269
  }
266
270
  for (const exit of lastArgExits) {
267
- graph.addEdge(call.info.id + '-exit', exit, { label: 0 /* CfgEdgeType.Fd */ });
271
+ graph.addEdge(callId + '-exit', exit, { label: 0 /* CfgEdgeType.Fd */ });
268
272
  }
269
273
  // should not contain any breaks, nexts, or returns, (except for the body if something like 'break()')
270
274
  return info;
@@ -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,14 @@ 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
+ import type { FlowrConfigOptions } from '../config';
18
+ 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
+ readonly flowrConfig: FlowrConfigOptions;
19
20
  }
20
21
  /**
21
22
  * This visitor extends on the {@link DataflowAwareCfgGuidedVisitor} by dispatching visitors for separate function calls as well,
@@ -40,7 +41,7 @@ export interface SemanticCfgGuidedVisitorConfiguration<OtherInfo = NoInfo, Cfg e
40
41
  *
41
42
  * Use {@link BasicCfgGuidedVisitor#start} to start the traversal.
42
43
  */
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> {
44
+ 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
45
  /**
45
46
  * A helper function to get the normalized AST node for the given id or fail if it does not exist.
46
47
  */
@@ -117,12 +118,21 @@ export declare class SemanticCfgGuidedVisitor<OtherInfo = NoInfo, Cfg extends Co
117
118
  * @protected
118
119
  */
119
120
  protected onDispatchFunctionCallOrigin(call: DataflowGraphVertexFunctionCall, origin: keyof typeof BuiltInProcessorMapper | string): void;
121
+ /**
122
+ * This event is called for the root program node, i.e., the program that is being analyzed.
123
+ *
124
+ * @protected
125
+ */
120
126
  protected onProgram(_data: RExpressionList<OtherInfo>): void;
121
127
  /**
122
128
  * A helper function to request the {@link getOriginInDfg|origins} of the given node.
123
129
  */
124
130
  protected getOrigins(id: NodeId): Origin[] | undefined;
125
- /** Called for every occurrence of a `NULL` in the program. */
131
+ /**
132
+ * Called for every occurrence of a `NULL` in the program.
133
+ *
134
+ * For other symbols that are not referenced as a variable, see {@link SemanticCfgGuidedVisitor#onSymbolConstant|`onSymbolConstant`}.
135
+ */
126
136
  protected onNullConstant(_data: {
127
137
  vertex: DataflowGraphVertexValue;
128
138
  node: RSymbol<OtherInfo & ParentInformation, 'NULL'>;
@@ -154,6 +164,18 @@ export declare class SemanticCfgGuidedVisitor<OtherInfo = NoInfo, Cfg extends Co
154
164
  vertex: DataflowGraphVertexValue;
155
165
  node: RLogical;
156
166
  }): void;
167
+ /**
168
+ * Called for every constant symbol value in the program.
169
+ *
170
+ * For example, `foo` in `library(foo)` or `a` in `l$a`. This most likely happens as part of non-standard-evaluation, i.e., the symbol is not evaluated to a value,
171
+ * but used as a symbol in and of itself.
172
+ *
173
+ * Please note, that due to its special behaviors, `NULL` is handled in {@link SemanticCfgGuidedVisitor#onNullConstant|`onNullConstant`} and not here.
174
+ */
175
+ protected onSymbolConstant(_data: {
176
+ vertex: DataflowGraphVertexValue;
177
+ node: RSymbol;
178
+ }): void;
157
179
  /**
158
180
  * Called for every variable that is read within the program.
159
181
  * You can use {@link getOrigins} to get the origins of the variable.
@@ -180,6 +202,7 @@ export declare class SemanticCfgGuidedVisitor<OtherInfo = NoInfo, Cfg extends Co
180
202
  */
181
203
  protected onFunctionDefinition(_data: {
182
204
  vertex: DataflowGraphVertexFunctionDefinition;
205
+ parameters?: readonly NodeId[];
183
206
  }): void;
184
207
  /**
185
208
  * This event triggers for every anonymous call within the program.
@@ -211,7 +234,7 @@ export declare class SemanticCfgGuidedVisitor<OtherInfo = NoInfo, Cfg extends Co
211
234
  *
212
235
  * This explicitly will not trigger for scenarios in which the function has no name (i.e., if it is anonymous).
213
236
  * 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.
237
+ * 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
238
  *
216
239
  * @protected
217
240
  */
@@ -282,9 +305,9 @@ export declare class SemanticCfgGuidedVisitor<OtherInfo = NoInfo, Cfg extends Co
282
305
  */
283
306
  protected onIfThenElseCall(_data: {
284
307
  call: DataflowGraphVertexFunctionCall;
285
- condition: FunctionArgument;
286
- then: FunctionArgument;
287
- else: FunctionArgument | undefined;
308
+ condition: NodeId | undefined;
309
+ then: NodeId | undefined;
310
+ else: NodeId | undefined;
288
311
  }): void;
289
312
  /**
290
313
  * This event triggers for every call to the `get` function, which is used to access variables in the global environment.
@@ -346,6 +369,8 @@ export declare class SemanticCfgGuidedVisitor<OtherInfo = NoInfo, Cfg extends Co
346
369
  */
347
370
  protected onSpecialBinaryOpCall(_data: {
348
371
  call: DataflowGraphVertexFunctionCall;
372
+ lhs?: FunctionArgument;
373
+ rhs?: FunctionArgument;
349
374
  }): void;
350
375
  /**
351
376
  * This event triggers for every call to R's pipe operator, i.e., for every call to `|>`.
@@ -354,6 +379,8 @@ export declare class SemanticCfgGuidedVisitor<OtherInfo = NoInfo, Cfg extends Co
354
379
  */
355
380
  protected onPipeCall(_data: {
356
381
  call: DataflowGraphVertexFunctionCall;
382
+ lhs?: FunctionArgument;
383
+ rhs?: FunctionArgument;
357
384
  }): void;
358
385
  /**
359
386
  * This event triggers for every call to the `quote` function, which is used to quote expressions.