@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.
- package/README.md +4 -4
- package/cli/repl/commands/repl-cfg.d.ts +2 -2
- package/cli/repl/commands/repl-cfg.js +4 -4
- package/cli/repl/commands/repl-commands.js +3 -3
- package/cli/repl/commands/repl-execute.js +2 -1
- package/cli/repl/server/connection.js +1 -1
- package/cli/script-core/statistics-helper-core.js +1 -1
- package/config.js +1 -1
- package/control-flow/basic-cfg-guided-visitor.d.ts +3 -3
- package/control-flow/cfg-dead-code.d.ts +4 -0
- package/control-flow/cfg-dead-code.js +81 -0
- package/control-flow/cfg-simplification.d.ts +17 -6
- package/control-flow/cfg-simplification.js +23 -19
- package/control-flow/control-flow-graph.d.ts +2 -1
- package/control-flow/control-flow-graph.js +1 -0
- package/control-flow/dfg-cfg-guided-visitor.d.ts +4 -4
- package/control-flow/dfg-cfg-guided-visitor.js +1 -1
- package/control-flow/extract-cfg.d.ts +2 -2
- package/control-flow/extract-cfg.js +70 -67
- package/control-flow/semantic-cfg-guided-visitor.d.ts +17 -8
- package/control-flow/semantic-cfg-guided-visitor.js +50 -17
- package/control-flow/simple-visitor.d.ts +4 -0
- package/control-flow/simple-visitor.js +14 -0
- package/control-flow/syntax-cfg-guided-visitor.d.ts +2 -2
- package/dataflow/environments/built-in-config.d.ts +1 -0
- package/dataflow/environments/built-in.d.ts +10 -1
- package/dataflow/environments/built-in.js +9 -3
- package/dataflow/environments/default-builtin-config.js +1 -1
- package/dataflow/environments/resolve-by-name.d.ts +0 -36
- package/dataflow/environments/resolve-by-name.js +0 -240
- package/dataflow/eval/resolve/alias-tracking.d.ts +87 -0
- package/dataflow/eval/resolve/alias-tracking.js +349 -0
- package/dataflow/eval/resolve/resolve.d.ts +34 -0
- package/dataflow/eval/resolve/resolve.js +93 -0
- package/dataflow/eval/values/general.d.ts +27 -0
- package/dataflow/eval/values/general.js +73 -0
- package/dataflow/eval/values/intervals/interval-constants.d.ts +4 -0
- package/dataflow/eval/values/intervals/interval-constants.js +27 -0
- package/dataflow/eval/values/logical/logical-constants.d.ts +7 -0
- package/dataflow/eval/values/logical/logical-constants.js +31 -0
- package/dataflow/eval/values/r-value.d.ts +58 -0
- package/dataflow/eval/values/r-value.js +90 -0
- package/dataflow/eval/values/scalar/scalar-consatnts.d.ts +15 -0
- package/dataflow/eval/values/scalar/scalar-consatnts.js +35 -0
- package/dataflow/eval/values/sets/set-constants.d.ts +7 -0
- package/dataflow/eval/values/sets/set-constants.js +34 -0
- package/dataflow/eval/values/string/string-constants.d.ts +8 -0
- package/dataflow/eval/values/string/string-constants.js +40 -0
- package/dataflow/eval/values/vectors/vector-constants.d.ts +14 -0
- package/dataflow/eval/values/vectors/vector-constants.js +35 -0
- package/dataflow/graph/unknown-replacement.d.ts +11 -0
- package/dataflow/graph/unknown-replacement.js +12 -0
- package/dataflow/graph/unknown-side-effect.d.ts +7 -0
- package/dataflow/graph/unknown-side-effect.js +13 -0
- package/dataflow/internal/process/functions/call/built-in/built-in-apply.js +8 -5
- package/dataflow/internal/process/functions/call/built-in/built-in-assignment.js +4 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-eval.js +12 -9
- package/dataflow/internal/process/functions/call/built-in/built-in-if-then-else.js +5 -4
- package/dataflow/internal/process/functions/call/built-in/built-in-replacement.js +9 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-source.js +12 -15
- package/dataflow/internal/process/functions/call/built-in/built-in-while-loop.js +23 -0
- package/dataflow/internal/process/functions/call/known-call-handling.js +2 -1
- package/documentation/doc-util/doc-cfg.d.ts +1 -1
- package/documentation/doc-util/doc-cfg.js +3 -3
- package/documentation/doc-util/doc-query.d.ts +6 -3
- package/documentation/doc-util/doc-query.js +3 -1
- package/documentation/print-cfg-wiki.js +31 -31
- package/documentation/print-dataflow-graph-wiki.js +4 -3
- package/documentation/print-engines-wiki.js +1 -1
- package/documentation/print-linter-wiki.d.ts +1 -0
- package/documentation/print-linter-wiki.js +76 -0
- package/documentation/print-query-wiki.js +80 -0
- package/linter/linter-executor.d.ts +9 -0
- package/linter/linter-executor.js +26 -0
- package/linter/linter-format.d.ts +65 -0
- package/linter/linter-format.js +9 -0
- package/linter/linter-rules.d.ts +42 -0
- package/linter/linter-rules.js +14 -0
- package/linter/rules/1-deprecated-functions.d.ts +34 -0
- package/linter/rules/1-deprecated-functions.js +54 -0
- package/linter/rules/2-file-path-validity.d.ts +48 -0
- package/linter/rules/2-file-path-validity.js +93 -0
- package/package.json +2 -1
- package/queries/catalog/call-context-query/call-context-query-executor.js +1 -1
- package/queries/catalog/call-context-query/call-context-query-format.d.ts +2 -2
- package/queries/catalog/call-context-query/call-context-query-format.js +5 -1
- package/queries/catalog/cluster-query/cluster-query-format.d.ts +2 -0
- package/queries/catalog/cluster-query/cluster-query-format.js +5 -1
- package/queries/catalog/config-query/config-query-format.d.ts +1 -0
- package/queries/catalog/config-query/config-query-format.js +2 -1
- package/queries/catalog/control-flow-query/control-flow-query-executor.d.ts +3 -0
- package/queries/catalog/control-flow-query/control-flow-query-executor.js +20 -0
- package/queries/catalog/control-flow-query/control-flow-query-format.d.ts +81 -0
- package/queries/catalog/control-flow-query/control-flow-query-format.js +34 -0
- package/queries/catalog/dataflow-lens-query/dataflow-lens-query-format.d.ts +1 -0
- package/queries/catalog/dataflow-lens-query/dataflow-lens-query-format.js +2 -1
- package/queries/catalog/dataflow-query/dataflow-query-format.d.ts +2 -0
- package/queries/catalog/dataflow-query/dataflow-query-format.js +9 -1
- package/queries/catalog/dependencies-query/dependencies-query-executor.js +33 -32
- package/queries/catalog/dependencies-query/dependencies-query-format.d.ts +1 -0
- package/queries/catalog/dependencies-query/dependencies-query-format.js +10 -1
- package/queries/catalog/happens-before-query/happens-before-query-format.d.ts +1 -0
- package/queries/catalog/happens-before-query/happens-before-query-format.js +2 -1
- package/queries/catalog/id-map-query/id-map-query-format.d.ts +1 -0
- package/queries/catalog/id-map-query/id-map-query-format.js +2 -1
- package/queries/catalog/lineage-query/lineage-query-format.d.ts +1 -0
- package/queries/catalog/lineage-query/lineage-query-format.js +5 -1
- package/queries/catalog/linter-query/linter-query-executor.d.ts +3 -0
- package/queries/catalog/linter-query/linter-query-executor.js +28 -0
- package/queries/catalog/linter-query/linter-query-format.d.ts +80 -0
- package/queries/catalog/linter-query/linter-query-format.js +44 -0
- package/queries/catalog/location-map-query/location-map-query-format.d.ts +1 -0
- package/queries/catalog/location-map-query/location-map-query-format.js +2 -1
- package/queries/catalog/normalized-ast-query/normalized-ast-query-format.d.ts +1 -0
- package/queries/catalog/normalized-ast-query/normalized-ast-query-format.js +2 -1
- package/queries/catalog/origin-query/origin-query-format.d.ts +2 -0
- package/queries/catalog/origin-query/origin-query-format.js +5 -1
- package/queries/catalog/project-query/project-query-executor.js +1 -1
- package/queries/catalog/project-query/project-query-format.d.ts +1 -0
- package/queries/catalog/project-query/project-query-format.js +2 -1
- package/queries/catalog/resolve-value-query/resolve-value-query-executor.js +3 -3
- package/queries/catalog/resolve-value-query/resolve-value-query-format.d.ts +3 -1
- package/queries/catalog/resolve-value-query/resolve-value-query-format.js +4 -23
- package/queries/catalog/search-query/search-query-format.d.ts +1 -0
- package/queries/catalog/search-query/search-query-format.js +5 -1
- package/queries/catalog/static-slice-query/static-slice-query-format.d.ts +2 -0
- package/queries/catalog/static-slice-query/static-slice-query-format.js +9 -1
- package/queries/query.d.ts +143 -1
- package/queries/query.js +4 -0
- package/r-bridge/lang-4.x/tree-sitter/tree-sitter-normalize.js +11 -4
- package/r-bridge/retriever.js +1 -1
- package/search/flowr-search-builder.d.ts +31 -2
- package/search/flowr-search-builder.js +30 -0
- package/search/flowr-search.d.ts +7 -1
- package/search/search-executor/search-enrichers.d.ts +73 -0
- package/search/search-executor/search-enrichers.js +101 -0
- package/search/search-executor/search-generators.d.ts +6 -1
- package/search/search-executor/search-generators.js +21 -1
- package/search/search-executor/search-mappers.d.ts +19 -0
- package/search/search-executor/search-mappers.js +21 -0
- package/search/search-executor/search-transformer.d.ts +12 -0
- package/search/search-executor/search-transformer.js +11 -1
- package/slicing/criterion/parse.d.ts +8 -0
- package/slicing/criterion/parse.js +20 -0
- 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.
|
|
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!">
|
|
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.
|
|
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.
|
|
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
|
|
5
|
-
export declare const
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
89
|
-
'controlflowbb*': repl_cfg_1.
|
|
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 })}
|
|
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.
|
|
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.
|
|
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
|
@@ -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<
|
|
4
|
-
readonly controlFlow:
|
|
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<
|
|
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
|
-
|
|
3
|
-
|
|
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
|
-
|
|
16
|
-
|
|
17
|
-
|
|
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
|
|
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
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
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
|
|
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
|
-
|
|
8
|
-
|
|
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<
|
|
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.
|
|
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
|
|
17
|
+
export declare function extractCfg<Info = ParentInformation>(ast: NormalizedAst<Info & ParentInformation>, graph?: DataflowGraph, simplifications?: readonly CfgSimplificationPassName[]): ControlFlowInformation;
|
|
18
18
|
/**
|
|
19
|
-
* Simplified version of {@link
|
|
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";
|