@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
package/README.md CHANGED
@@ -51,7 +51,7 @@ It offers a wide variety of features, for example:
51
51
 
52
52
  ```shell
53
53
  $ docker run -it --rm eagleoutice/flowr # or npm run flowr
54
- flowR repl using flowR v2.2.12, R v4.4.3 (r-shell engine)
54
+ flowR repl using flowR v2.2.14, R v4.4.3 (r-shell engine)
55
55
  R> :slicer test/testfiles/example.R --criterion "11@sum"
56
56
  ```
57
57
 
@@ -98,7 +98,7 @@ It offers a wide variety of features, for example:
98
98
 
99
99
 
100
100
  * 🚀 **fast data- and control-flow graphs**\
101
- Within just <i><span title="This measurement is automatically fetched from the latest benchmark!">124.8 ms</span></i> (as of Mar 17, 2025),
101
+ Within just <i><span title="This measurement is automatically fetched from the latest benchmark!">133.8 ms</span></i> (as of May 31, 2025),
102
102
  _flowR_ can analyze the data- and control-flow of the average real-world R script. See the [benchmarks](https://flowr-analysis.github.io/flowr/wiki/stats/benchmark) for more information,
103
103
  and consult the [wiki pages](https://github.com/flowr-analysis/flowr/wiki/Dataflow-Graph) for more details on the dataflow graph.
104
104
 
@@ -134,7 +134,7 @@ It offers a wide variety of features, for example:
134
134
 
135
135
  ```shell
136
136
  $ docker run -it --rm eagleoutice/flowr # or npm run flowr
137
- flowR repl using flowR v2.2.12, R v4.4.3 (r-shell engine)
137
+ flowR repl using flowR v2.2.14, R v4.4.3 (r-shell engine)
138
138
  R> :dataflow* test/testfiles/example.R
139
139
  ```
140
140
 
@@ -435,7 +435,7 @@ It offers a wide variety of features, for example:
435
435
  ```
436
436
 
437
437
 
438
- (The analysis required _22.6 ms_ (including parse and normalize, using the [r-shell](https://github.com/flowr-analysis/flowr/wiki/Engines) engine) within the generation environment.)
438
+ (The analysis required _22.8 ms_ (including parse and normalize, using the [r-shell](https://github.com/flowr-analysis/flowr/wiki/Engines) engine) within the generation environment.)
439
439
 
440
440
 
441
441
 
@@ -1,5 +1,5 @@
1
1
  import type { ReplCommand } from './repl-main';
2
2
  export declare const controlflowCommand: ReplCommand;
3
3
  export declare const controlflowStarCommand: ReplCommand;
4
- export declare const controlflowBBCommand: ReplCommand;
5
- export declare const controlflowBBStarCommand: ReplCommand;
4
+ export declare const controlflowBbCommand: ReplCommand;
5
+ export declare const controlflowBbStarCommand: ReplCommand;
@@ -33,7 +33,7 @@ var __importStar = (this && this.__importStar) || (function () {
33
33
  };
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.controlflowBBStarCommand = exports.controlflowBBCommand = exports.controlflowStarCommand = exports.controlflowCommand = void 0;
36
+ exports.controlflowBbStarCommand = exports.controlflowBbCommand = exports.controlflowStarCommand = exports.controlflowCommand = void 0;
37
37
  const extract_cfg_1 = require("../../../control-flow/extract-cfg");
38
38
  const default_pipelines_1 = require("../../../core/steps/pipeline/default-pipelines");
39
39
  const retriever_1 = require("../../../r-bridge/retriever");
@@ -53,7 +53,7 @@ function formatInfo(out, type) {
53
53
  }
54
54
  async function produceAndPrintCfg(shell, remainingLine, output, simplifications, cfgConverter) {
55
55
  const result = await controlflow(shell, handleString(remainingLine));
56
- const cfg = (0, extract_cfg_1.extractCFG)(result.normalize, result.dataflow.graph, [...cfg_simplification_1.DefaultCfgSimplificationOrder, ...simplifications]);
56
+ const cfg = (0, extract_cfg_1.extractCfg)(result.normalize, result.dataflow.graph, [...cfg_simplification_1.DefaultCfgSimplificationOrder, ...simplifications]);
57
57
  const mermaid = cfgConverter(cfg, result.normalize);
58
58
  output.stdout(mermaid);
59
59
  try {
@@ -82,7 +82,7 @@ exports.controlflowStarCommand = {
82
82
  await produceAndPrintCfg(shell, remainingLine, output, [], cfg_1.cfgToMermaidUrl);
83
83
  }
84
84
  };
85
- exports.controlflowBBCommand = {
85
+ exports.controlflowBbCommand = {
86
86
  description: `Get mermaid code for the control-flow graph with basic blocks, start with '${retriever_1.fileProtocol}' to indicate a file`,
87
87
  usageExample: ':controlflowbb',
88
88
  aliases: ['cfgb', 'cfb'],
@@ -91,7 +91,7 @@ exports.controlflowBBCommand = {
91
91
  await produceAndPrintCfg(shell, remainingLine, output, ['to-basic-blocks'], cfg_1.cfgToMermaid);
92
92
  }
93
93
  };
94
- exports.controlflowBBStarCommand = {
94
+ exports.controlflowBbStarCommand = {
95
95
  description: 'Returns the URL to mermaid.live',
96
96
  usageExample: ':controlflowbb*',
97
97
  aliases: ['cfgb*', 'cfb*'],
@@ -53,7 +53,7 @@ exports.helpCommand = {
53
53
  fn: output => {
54
54
  initCommandMapping();
55
55
  output.stdout(`
56
- If enabled ('--r-session-access'), you can just enter R expressions which get evaluated right away:
56
+ If enabled ('--r-session-access' and if using the 'r-shell' engine), you can just enter R expressions which get evaluated right away:
57
57
  ${prompt_1.rawPrompt} ${(0, ansi_1.bold)('1 + 1', output.formatter)}
58
58
  ${(0, ansi_1.italic)('[1] 2', output.formatter)}
59
59
 
@@ -85,8 +85,8 @@ const _commands = {
85
85
  'dataflowsimple*': repl_dataflow_1.dataflowSimpleStarCommand,
86
86
  'controlflow': repl_cfg_1.controlflowCommand,
87
87
  'controlflow*': repl_cfg_1.controlflowStarCommand,
88
- 'controlflowbb': repl_cfg_1.controlflowBBCommand,
89
- 'controlflowbb*': repl_cfg_1.controlflowBBStarCommand,
88
+ 'controlflowbb': repl_cfg_1.controlflowBbCommand,
89
+ 'controlflowbb*': repl_cfg_1.controlflowBbStarCommand,
90
90
  'lineage': repl_lineage_1.lineageCommand,
91
91
  'query': repl_query_1.queryCommand,
92
92
  'query*': repl_query_1.queryStarCommand
@@ -6,7 +6,8 @@ const ansi_1 = require("../../../util/text/ansi");
6
6
  const shell_1 = require("../../../r-bridge/shell");
7
7
  async function tryExecuteRShellCommand(output, parser, statement, allowRSessionAccess) {
8
8
  if (!allowRSessionAccess) {
9
- output.stderr(`${output.formatter.format('You are not allowed to execute arbitrary R code.', { style: 1 /* FontStyles.Bold */, color: 1 /* Colors.Red */, effect: ansi_1.ColorEffect.Foreground })}\nIf you want to do so, please restart flowR with the ${output.formatter.format('--r-session-access', { style: 1 /* FontStyles.Bold */ })} flag. Please be careful of the security implications of this action.`);
9
+ output.stderr(`${output.formatter.format('You are not allowed to execute arbitrary R code.', { style: 1 /* FontStyles.Bold */, color: 1 /* Colors.Red */, effect: ansi_1.ColorEffect.Foreground })}
10
+ If you want to do so, please restart flowR with the ${output.formatter.format('--r-session-access', { style: 1 /* FontStyles.Bold */ })} flag${parser.name !== 'r-shell' ? '. Additionally, please enable the r-shell engine, e.g., with ' + output.formatter.format('--default-engine r-shell', { style: 1 /* FontStyles.Bold */ }) : ''}. Please be careful of the security implications of this action.`);
10
11
  }
11
12
  else if (parser instanceof shell_1.RShell) {
12
13
  await executeRShellCommand(output, parser, statement);
@@ -160,7 +160,7 @@ class FlowRServerConnection {
160
160
  async sendFileAnalysisResponse(slicer, results, message) {
161
161
  let cfg = undefined;
162
162
  if (message.cfg) {
163
- cfg = (0, extract_cfg_1.extractCFG)(results.normalize, results.dataflow?.graph);
163
+ cfg = (0, extract_cfg_1.extractCfg)(results.normalize, results.dataflow?.graph);
164
164
  }
165
165
  const config = () => ({ context: message.filename ?? 'unknown', getId: (0, quads_1.defaultQuadIdGenerator)() });
166
166
  const sanitizedResults = sanitizeAnalysisResults(results);
@@ -58,7 +58,7 @@ async function getStatsForSingleFile(options) {
58
58
  if (stats.outputs.size === 1) {
59
59
  if (options['dump-json']) {
60
60
  const [, output] = [...stats.outputs.entries()][0];
61
- const cfg = (0, extract_cfg_1.extractCFG)(output.normalize, output.dataflow.graph);
61
+ const cfg = (0, extract_cfg_1.extractCfg)(output.normalize, output.dataflow.graph);
62
62
  statistics_file_1.statisticsFileProvider.append('output-json', 'parse', await (0, print_1.printStepResult)(_00_parse_1.PARSE_WITH_R_SHELL_STEP, output.parse, 2 /* StepOutputFormat.Json */));
63
63
  statistics_file_1.statisticsFileProvider.append('output-json', 'normalize', await (0, print_1.printStepResult)(_10_normalize_1.NORMALIZE, output.normalize, 2 /* StepOutputFormat.Json */));
64
64
  statistics_file_1.statisticsFileProvider.append('output-json', 'dataflow', await (0, print_1.printStepResult)(_20_dataflow_1.STATIC_DATAFLOW, output.dataflow, 2 /* StepOutputFormat.Json */));
package/config.js CHANGED
@@ -67,7 +67,7 @@ exports.defaultConfigOptions = {
67
67
  }
68
68
  },
69
69
  engines: [],
70
- defaultEngine: 'r-shell',
70
+ defaultEngine: 'tree-sitter',
71
71
  solver: {
72
72
  variables: VariableResolve.Alias,
73
73
  evalStrings: true,
@@ -1,7 +1,7 @@
1
1
  import type { CfgBasicBlockVertex, CfgEndMarkerVertex, CfgExpressionVertex, CfgMidMarkerVertex, CfgSimpleVertex, CfgStatementVertex, ControlFlowInformation } from './control-flow-graph';
2
2
  import type { NodeId } from '../r-bridge/lang-4.x/ast/model/processing/node-id';
3
- export interface BasicCfgGuidedVisitorConfiguration<Cfg extends ControlFlowInformation = ControlFlowInformation> {
4
- readonly controlFlow: Cfg;
3
+ export interface BasicCfgGuidedVisitorConfiguration<ControlFlow extends ControlFlowInformation = ControlFlowInformation> {
4
+ readonly controlFlow: ControlFlow;
5
5
  readonly defaultVisitingOrder: 'forward' | 'backward';
6
6
  }
7
7
  /**
@@ -11,7 +11,7 @@ export interface BasicCfgGuidedVisitorConfiguration<Cfg extends ControlFlowInfor
11
11
  *
12
12
  * Use {@link BasicCfgGuidedVisitor#start} to start the traversal.
13
13
  */
14
- export declare class BasicCfgGuidedVisitor<Cfg extends ControlFlowInformation = ControlFlowInformation, Config extends BasicCfgGuidedVisitorConfiguration<Cfg> = BasicCfgGuidedVisitorConfiguration<Cfg>> {
14
+ export declare class BasicCfgGuidedVisitor<ControlFlow extends ControlFlowInformation = ControlFlowInformation, Config extends BasicCfgGuidedVisitorConfiguration<ControlFlow> = BasicCfgGuidedVisitorConfiguration<ControlFlow>> {
15
15
  protected readonly config: Config;
16
16
  protected readonly visited: Map<NodeId, number>;
17
17
  constructor(config: Config);
@@ -0,0 +1,4 @@
1
+ import type { ControlFlowInformation } from './control-flow-graph';
2
+ import type { CfgPassInfo } from './cfg-simplification';
3
+ /** Breaks unsatisfiable control dependencies */
4
+ export declare function cfgAnalyzeDeadCode(cfg: ControlFlowInformation, info: CfgPassInfo): ControlFlowInformation;
@@ -0,0 +1,81 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.cfgAnalyzeDeadCode = cfgAnalyzeDeadCode;
4
+ const logic_1 = require("../util/logic");
5
+ const semantic_cfg_guided_visitor_1 = require("./semantic-cfg-guided-visitor");
6
+ const alias_tracking_1 = require("../dataflow/eval/resolve/alias-tracking");
7
+ const log_1 = require("../util/log");
8
+ const r_function_call_1 = require("../r-bridge/lang-4.x/ast/model/nodes/r-function-call");
9
+ const general_1 = require("../dataflow/eval/values/general");
10
+ const r_value_1 = require("../dataflow/eval/values/r-value");
11
+ class CfgConditionalDeadCodeRemoval extends semantic_cfg_guided_visitor_1.SemanticCfgGuidedVisitor {
12
+ cachedConditions = new Map();
13
+ getValue(id) {
14
+ const has = this.cachedConditions.get(id);
15
+ if (has) {
16
+ return has;
17
+ }
18
+ this.visitNode(id);
19
+ return this.cachedConditions.get(id) ?? logic_1.Ternary.Maybe;
20
+ }
21
+ unableToCalculateValue(id) {
22
+ this.cachedConditions.set(id, logic_1.Ternary.Maybe);
23
+ }
24
+ storeDefiniteValue(id, value) {
25
+ this.cachedConditions.set(id, value ? logic_1.Ternary.Always : logic_1.Ternary.Never);
26
+ }
27
+ startVisitor() {
28
+ for (const [from, targets] of this.config.controlFlow.graph.edges()) {
29
+ for (const [target, edge] of targets) {
30
+ if (edge.label === 1 /* CfgEdgeType.Cd */) {
31
+ const og = this.getValue(edge.caused);
32
+ if (og === logic_1.Ternary.Always && edge.when === 'FALSE') {
33
+ this.config.controlFlow.graph.removeEdge(from, target);
34
+ }
35
+ else if (og === logic_1.Ternary.Never && edge.when === 'TRUE') {
36
+ this.config.controlFlow.graph.removeEdge(from, target);
37
+ }
38
+ }
39
+ }
40
+ }
41
+ }
42
+ handleValuesFor(id, valueId) {
43
+ const values = (0, general_1.valueSetGuard)((0, alias_tracking_1.resolveIdToValue)(valueId, { graph: this.config.dfg, full: true, idMap: this.config.normalizedAst.idMap }));
44
+ if (values === undefined || values.elements.length !== 1 || values.elements[0].type != 'logical' || !(0, r_value_1.isValue)(values.elements[0].value)) {
45
+ this.unableToCalculateValue(id);
46
+ return;
47
+ }
48
+ /* we should translate this to truthy later */
49
+ this.storeDefiniteValue(id, Boolean(values.elements[0].value));
50
+ }
51
+ handleWithCondition(data) {
52
+ const id = data.call.id;
53
+ if (data.condition === undefined || data.condition === r_function_call_1.EmptyArgument) {
54
+ this.unableToCalculateValue(id);
55
+ return;
56
+ }
57
+ this.handleValuesFor(id, typeof data.condition === 'object' ? data.condition.nodeId : data.condition);
58
+ }
59
+ onIfThenElseCall(data) {
60
+ this.handleWithCondition(data);
61
+ }
62
+ onWhileLoopCall(data) {
63
+ this.handleWithCondition(data);
64
+ }
65
+ }
66
+ /** Breaks unsatisfiable control dependencies */
67
+ function cfgAnalyzeDeadCode(cfg, info) {
68
+ if (!info.ast || !info.dfg) {
69
+ log_1.log.warn('cfgAnalyzeDeadCode called without ast or dfg, skipping dead code analysis');
70
+ return cfg;
71
+ }
72
+ const visitor = new CfgConditionalDeadCodeRemoval({
73
+ controlFlow: cfg,
74
+ normalizedAst: info.ast,
75
+ dfg: info.dfg,
76
+ defaultVisitingOrder: 'forward'
77
+ });
78
+ visitor.start();
79
+ return cfg;
80
+ }
81
+ //# sourceMappingURL=cfg-dead-code.js.map
@@ -1,7 +1,15 @@
1
1
  import type { ControlFlowInformation } from './control-flow-graph';
2
- export type CfgSimplificationPass = (cfg: ControlFlowInformation) => ControlFlowInformation;
3
- declare const CfgSimplificationPasses: {
2
+ import type { NormalizedAst } from '../r-bridge/lang-4.x/ast/model/processing/decorate';
3
+ import type { DataflowGraph } from '../dataflow/graph/graph';
4
+ import { cfgAnalyzeDeadCode } from './cfg-dead-code';
5
+ export interface CfgPassInfo {
6
+ ast?: NormalizedAst;
7
+ dfg?: DataflowGraph;
8
+ }
9
+ export type CfgSimplificationPass = (cfg: ControlFlowInformation, info: CfgPassInfo) => ControlFlowInformation;
10
+ export declare const CfgSimplificationPasses: {
4
11
  readonly 'unique-cf-sets': typeof uniqueControlFlowSets;
12
+ readonly 'analyze-dead-code': typeof cfgAnalyzeDeadCode;
5
13
  readonly 'remove-dead-code': typeof cfgRemoveDeadCode;
6
14
  readonly 'to-basic-blocks': typeof toBasicBlocks;
7
15
  };
@@ -11,8 +19,11 @@ export declare const DefaultCfgSimplificationOrder: ["unique-cf-sets"];
11
19
  * Simplify the control flow information by applying the given passes.
12
20
  * This may reduce the vertex count, in- and outgoing edges, entry and exit points, etc.
13
21
  */
14
- export declare function simplifyControlFlowInformation(cfg: ControlFlowInformation, passes?: readonly CfgSimplificationPassName[]): ControlFlowInformation;
15
- declare function uniqueControlFlowSets(cfg: ControlFlowInformation): ControlFlowInformation;
16
- declare function cfgRemoveDeadCode(cfg: ControlFlowInformation): ControlFlowInformation;
17
- declare function toBasicBlocks(cfg: ControlFlowInformation): ControlFlowInformation;
22
+ export declare function simplifyControlFlowInformation(cfg: ControlFlowInformation, info: CfgPassInfo, passes?: readonly CfgSimplificationPassName[]): ControlFlowInformation;
23
+ /**
24
+ * removes dead vertices and edges from the control flow graph.
25
+ */
26
+ declare function cfgRemoveDeadCode(cfg: ControlFlowInformation, _info?: CfgPassInfo): ControlFlowInformation;
27
+ declare function uniqueControlFlowSets(cfg: ControlFlowInformation, _info?: CfgPassInfo): ControlFlowInformation;
28
+ declare function toBasicBlocks(cfg: ControlFlowInformation, _info?: CfgPassInfo): ControlFlowInformation;
18
29
  export {};
@@ -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
@@ -70,7 +70,7 @@ export declare function equalVertex(a: CfgSimpleVertex, b: CfgSimpleVertex): boo
70
70
  interface CfgFlowDependencyEdge extends MergeableRecord {
71
71
  label: CfgEdgeType.Fd;
72
72
  }
73
- interface CfgControlDependencyEdge extends MergeableRecord {
73
+ export interface CfgControlDependencyEdge extends MergeableRecord {
74
74
  label: CfgEdgeType.Cd;
75
75
  /** the id which caused the control dependency */
76
76
  caused: NodeId;
@@ -166,6 +166,7 @@ export interface ReadOnlyControlFlowGraph {
166
166
  */
167
167
  export declare class ControlFlowGraph<Vertex extends CfgSimpleVertex = CfgSimpleVertex> implements ReadOnlyControlFlowGraph {
168
168
  private readonly rootVertices;
169
+ /** Nesting-Independent vertex information, mapping the id to the vertex */
169
170
  private readonly vertexInformation;
170
171
  /** 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
172
  private readonly bbChildren;
@@ -55,6 +55,7 @@ function equalVertex(a, b) {
55
55
  */
56
56
  class ControlFlowGraph {
57
57
  rootVertices = new Set();
58
+ /** Nesting-Independent vertex information, mapping the id to the vertex */
58
59
  vertexInformation = new Map();
59
60
  /** 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
61
  bbChildren = new Map();
@@ -1,18 +1,18 @@
1
1
  import type { CfgExpressionVertex, CfgStatementVertex, 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
9
  }
10
10
  /**
11
11
  * This visitor extends on the {@link BasicCfgGuidedVisitor} by dispatching visitors based on the dataflow graph.
12
12
  *
13
13
  * Use {@link BasicCfgGuidedVisitor#start} to start the traversal.
14
14
  */
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> {
15
+ 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
16
  /**
17
17
  * Get the dataflow graph vertex for the given id
18
18
  */
@@ -14,7 +14,7 @@ class DataflowAwareCfgGuidedVisitor extends basic_cfg_guided_visitor_1.BasicCfgG
14
14
  * Get the dataflow graph vertex for the given id
15
15
  */
16
16
  getDataflowGraph(id) {
17
- return this.config.dataflow.graph.getVertex(id);
17
+ return this.config.dfg.getVertex(id);
18
18
  }
19
19
  onStatementNode(node) {
20
20
  super.onStatementNode(node);
@@ -14,9 +14,9 @@ import type { CfgSimplificationPassName } from './cfg-simplification';
14
14
  *
15
15
  * @see {@link extractSimpleCfg} - for a simplified version of this function
16
16
  */
17
- export declare function extractCFG<Info = ParentInformation>(ast: NormalizedAst<Info>, graph?: DataflowGraph, simplifications?: readonly CfgSimplificationPassName[]): ControlFlowInformation;
17
+ export declare function extractCfg<Info = ParentInformation>(ast: NormalizedAst<Info & ParentInformation>, graph?: DataflowGraph, simplifications?: readonly CfgSimplificationPassName[]): ControlFlowInformation;
18
18
  /**
19
- * Simplified version of {@link extractCFG} that is much quicker, but much simpler!
19
+ * Simplified version of {@link extractCfg} that is much quicker, but much simpler!
20
20
  */
21
21
  export declare function extractSimpleCfg<Info = ParentInformation>(ast: NormalizedAst<Info>): ControlFlowInformation<import("./control-flow-graph").CfgSimpleVertex>;
22
22
  export declare const ResolvedCallSuffix = "-resolved-call-exit";