@eagleoutice/flowr 2.2.15 → 2.3.0
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 +226 -6
- package/abstract-interpretation/data-frame/absint-info.d.ts +109 -0
- package/abstract-interpretation/data-frame/absint-info.js +31 -0
- package/abstract-interpretation/data-frame/absint-visitor.d.ts +59 -0
- package/abstract-interpretation/data-frame/absint-visitor.js +173 -0
- package/abstract-interpretation/data-frame/domain.d.ts +107 -0
- package/abstract-interpretation/data-frame/domain.js +315 -0
- package/abstract-interpretation/data-frame/mappers/access-mapper.d.ts +17 -0
- package/abstract-interpretation/data-frame/mappers/access-mapper.js +166 -0
- package/abstract-interpretation/data-frame/mappers/arguments.d.ts +117 -0
- package/abstract-interpretation/data-frame/mappers/arguments.js +188 -0
- package/abstract-interpretation/data-frame/mappers/assignment-mapper.d.ts +20 -0
- package/abstract-interpretation/data-frame/mappers/assignment-mapper.js +34 -0
- package/abstract-interpretation/data-frame/mappers/function-mapper.d.ts +261 -0
- package/abstract-interpretation/data-frame/mappers/function-mapper.js +1219 -0
- package/abstract-interpretation/data-frame/mappers/replacement-mapper.d.ts +12 -0
- package/abstract-interpretation/data-frame/mappers/replacement-mapper.js +206 -0
- package/abstract-interpretation/data-frame/resolve-args.d.ts +42 -0
- package/abstract-interpretation/data-frame/resolve-args.js +118 -0
- package/abstract-interpretation/data-frame/semantics.d.ts +213 -0
- package/abstract-interpretation/data-frame/semantics.js +366 -0
- package/abstract-interpretation/data-frame/shape-inference.d.ts +38 -0
- package/abstract-interpretation/data-frame/shape-inference.js +117 -0
- package/benchmark/slicer.d.ts +18 -2
- package/benchmark/slicer.js +143 -5
- package/benchmark/stats/print.js +123 -45
- package/benchmark/stats/size-of.d.ts +7 -0
- package/benchmark/stats/size-of.js +1 -0
- package/benchmark/stats/stats.d.ts +30 -1
- package/benchmark/stats/stats.js +4 -2
- package/benchmark/summarizer/data.d.ts +33 -2
- package/benchmark/summarizer/first-phase/input.js +5 -1
- package/benchmark/summarizer/first-phase/process.d.ts +2 -1
- package/benchmark/summarizer/first-phase/process.js +49 -3
- package/benchmark/summarizer/second-phase/process.js +101 -3
- package/cli/benchmark-app.d.ts +2 -0
- package/cli/benchmark-app.js +5 -1
- package/cli/benchmark-helper-app.d.ts +2 -0
- package/cli/benchmark-helper-app.js +13 -8
- package/cli/common/options.js +4 -0
- package/cli/export-quads-app.js +2 -1
- package/cli/flowr.js +58 -57
- package/cli/repl/commands/repl-cfg.js +13 -13
- package/cli/repl/commands/repl-commands.js +2 -2
- package/cli/repl/commands/repl-dataflow.js +10 -10
- package/cli/repl/commands/repl-execute.d.ts +2 -3
- package/cli/repl/commands/repl-execute.js +4 -4
- package/cli/repl/commands/repl-lineage.js +4 -4
- package/cli/repl/commands/repl-main.d.ts +12 -1
- package/cli/repl/commands/repl-normalize.js +6 -6
- package/cli/repl/commands/repl-parse.js +2 -2
- package/cli/repl/commands/repl-query.js +9 -9
- package/cli/repl/commands/repl-version.js +1 -1
- package/cli/repl/core.d.ts +5 -2
- package/cli/repl/core.js +10 -8
- package/cli/repl/server/connection.d.ts +3 -1
- package/cli/repl/server/connection.js +7 -5
- package/cli/repl/server/server.d.ts +3 -2
- package/cli/repl/server/server.js +4 -2
- package/cli/script-core/statistics-core.d.ts +2 -1
- package/cli/script-core/statistics-core.js +2 -2
- package/cli/script-core/statistics-helper-core.d.ts +2 -1
- package/cli/script-core/statistics-helper-core.js +5 -4
- package/cli/slicer-app.js +4 -2
- package/cli/statistics-app.js +2 -1
- package/cli/statistics-helper-app.js +2 -1
- package/config.d.ts +43 -10
- package/config.js +47 -43
- package/control-flow/cfg-dead-code.js +45 -2
- package/control-flow/cfg-simplification.d.ts +2 -0
- package/control-flow/control-flow-graph.d.ts +2 -0
- package/control-flow/control-flow-graph.js +8 -0
- package/control-flow/dfg-cfg-guided-visitor.d.ts +5 -3
- package/control-flow/dfg-cfg-guided-visitor.js +15 -4
- package/control-flow/extract-cfg.d.ts +4 -2
- package/control-flow/extract-cfg.js +4 -3
- package/control-flow/semantic-cfg-guided-visitor.d.ts +20 -2
- package/control-flow/semantic-cfg-guided-visitor.js +24 -4
- package/core/pipeline-executor.d.ts +4 -1
- package/core/pipeline-executor.js +6 -5
- package/core/steps/all/core/10-normalize.d.ts +2 -0
- package/core/steps/all/core/10-normalize.js +1 -1
- package/core/steps/all/core/11-normalize-tree-sitter.d.ts +2 -1
- package/core/steps/all/core/11-normalize-tree-sitter.js +2 -2
- package/core/steps/all/core/20-dataflow.d.ts +2 -1
- package/core/steps/all/core/20-dataflow.js +2 -2
- package/core/steps/all/static-slicing/00-slice.d.ts +2 -1
- package/core/steps/all/static-slicing/00-slice.js +2 -2
- package/core/steps/pipeline/default-pipelines.d.ts +32 -31
- package/core/steps/pipeline/default-pipelines.js +8 -8
- package/core/steps/pipeline-step.d.ts +2 -1
- package/dataflow/environments/built-in-config.d.ts +3 -3
- package/dataflow/environments/built-in.d.ts +11 -3
- package/dataflow/environments/built-in.js +5 -3
- package/dataflow/environments/default-builtin-config.js +4 -2
- package/dataflow/environments/define.d.ts +2 -1
- package/dataflow/environments/define.js +4 -5
- package/dataflow/environments/remove.d.ts +6 -0
- package/dataflow/environments/remove.js +29 -0
- package/dataflow/eval/resolve/alias-tracking.d.ts +7 -2
- package/dataflow/eval/resolve/alias-tracking.js +11 -8
- package/dataflow/eval/resolve/resolve-argument.d.ts +8 -0
- package/dataflow/eval/resolve/resolve-argument.js +118 -0
- package/dataflow/eval/resolve/resolve.d.ts +65 -18
- package/dataflow/eval/resolve/resolve.js +144 -48
- package/dataflow/eval/values/string/string-constants.d.ts +1 -1
- package/dataflow/eval/values/string/string-constants.js +7 -2
- package/dataflow/extractor.d.ts +2 -1
- package/dataflow/extractor.js +2 -1
- package/dataflow/internal/process/functions/call/built-in/built-in-access.js +5 -6
- package/dataflow/internal/process/functions/call/built-in/built-in-apply.js +1 -1
- package/dataflow/internal/process/functions/call/built-in/built-in-assignment.d.ts +4 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-assignment.js +11 -11
- package/dataflow/internal/process/functions/call/built-in/built-in-eval.js +10 -11
- package/dataflow/internal/process/functions/call/built-in/built-in-expression-list.js +7 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-for-loop.js +2 -3
- package/dataflow/internal/process/functions/call/built-in/built-in-if-then-else.js +1 -1
- package/dataflow/internal/process/functions/call/built-in/built-in-list.js +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-replacement.js +2 -3
- package/dataflow/internal/process/functions/call/built-in/built-in-source.d.ts +6 -3
- package/dataflow/internal/process/functions/call/built-in/built-in-source.js +19 -15
- package/dataflow/internal/process/functions/call/built-in/built-in-vector.js +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-while-loop.js +1 -1
- package/dataflow/internal/process/functions/call/common.js +1 -1
- package/dataflow/internal/process/functions/process-parameter.js +1 -1
- package/dataflow/origin/dfg-get-symbol-refs.d.ts +21 -0
- package/dataflow/origin/dfg-get-symbol-refs.js +50 -0
- package/dataflow/processor.d.ts +5 -0
- package/documentation/doc-util/doc-cfg.js +4 -3
- package/documentation/doc-util/doc-code.d.ts +1 -1
- package/documentation/doc-util/doc-dfg.js +3 -2
- package/documentation/doc-util/doc-functions.d.ts +24 -0
- package/documentation/doc-util/doc-functions.js +65 -0
- package/documentation/doc-util/doc-normalized-ast.js +3 -2
- package/documentation/doc-util/doc-print.d.ts +5 -0
- package/documentation/doc-util/doc-print.js +36 -0
- package/documentation/doc-util/doc-query.js +13 -2
- package/documentation/doc-util/doc-repl.js +2 -1
- package/documentation/doc-util/doc-search.js +3 -2
- package/documentation/doc-util/doc-types.d.ts +28 -6
- package/documentation/doc-util/doc-types.js +89 -45
- package/documentation/print-cfg-wiki.js +6 -7
- package/documentation/print-core-wiki.js +5 -5
- package/documentation/print-dataflow-graph-wiki.js +10 -10
- package/documentation/print-engines-wiki.js +1 -2
- package/documentation/print-faq-wiki.js +8 -2
- package/documentation/print-interface-wiki.js +12 -2
- package/documentation/print-linter-issue.d.ts +1 -0
- package/documentation/print-linter-issue.js +71 -0
- package/documentation/print-linter-wiki.js +223 -34
- package/documentation/print-linting-and-testing-wiki.js +2 -4
- package/documentation/print-normalized-ast-wiki.js +3 -3
- package/documentation/print-query-wiki.js +18 -2
- package/documentation/print-readme.js +24 -1
- package/documentation/print-search-wiki.js +1 -2
- package/linter/linter-executor.d.ts +3 -1
- package/linter/linter-executor.js +3 -2
- package/linter/linter-format.d.ts +67 -7
- package/linter/linter-format.js +12 -1
- package/linter/linter-rules.d.ts +178 -16
- package/linter/linter-rules.js +14 -4
- package/linter/linter-tags.d.ts +80 -0
- package/linter/linter-tags.js +85 -0
- package/linter/rules/absolute-path.d.ts +71 -0
- package/linter/rules/absolute-path.js +177 -0
- package/linter/rules/dataframe-access-validation.d.ts +53 -0
- package/linter/rules/dataframe-access-validation.js +116 -0
- package/linter/rules/deprecated-functions.d.ts +43 -0
- package/linter/rules/deprecated-functions.js +58 -0
- package/linter/rules/{2-file-path-validity.d.ts → file-path-validity.d.ts} +16 -6
- package/linter/rules/{2-file-path-validity.js → file-path-validity.js} +21 -13
- package/linter/rules/naming-convention.d.ts +71 -0
- package/linter/rules/naming-convention.js +168 -0
- package/linter/rules/seeded-randomness.d.ts +65 -0
- package/linter/rules/seeded-randomness.js +122 -0
- package/linter/rules/unused-definition.d.ts +41 -0
- package/linter/rules/unused-definition.js +105 -0
- package/package.json +5 -2
- package/queries/base-query-format.d.ts +2 -0
- package/queries/catalog/call-context-query/call-context-query-executor.d.ts +1 -1
- package/queries/catalog/call-context-query/call-context-query-executor.js +2 -2
- package/queries/catalog/cluster-query/cluster-query-format.d.ts +1 -1
- package/queries/catalog/config-query/config-query-executor.d.ts +1 -1
- package/queries/catalog/config-query/config-query-executor.js +2 -3
- package/queries/catalog/control-flow-query/control-flow-query-executor.d.ts +1 -1
- package/queries/catalog/control-flow-query/control-flow-query-executor.js +2 -2
- package/queries/catalog/control-flow-query/control-flow-query-format.d.ts +1 -1
- package/queries/catalog/dataflow-lens-query/dataflow-lens-query-format.d.ts +1 -1
- package/queries/catalog/dataflow-query/dataflow-query-format.d.ts +1 -1
- package/queries/catalog/dependencies-query/dependencies-query-executor.js +4 -116
- package/queries/catalog/dependencies-query/dependencies-query-format.d.ts +1 -1
- package/queries/catalog/df-shape-query/df-shape-query-executor.d.ts +3 -0
- package/queries/catalog/df-shape-query/df-shape-query-executor.js +46 -0
- package/queries/catalog/df-shape-query/df-shape-query-format.d.ts +72 -0
- package/queries/catalog/df-shape-query/df-shape-query-format.js +31 -0
- package/queries/catalog/happens-before-query/happens-before-query-format.d.ts +1 -1
- package/queries/catalog/id-map-query/id-map-query-format.d.ts +1 -1
- package/queries/catalog/lineage-query/lineage-query-format.d.ts +1 -1
- package/queries/catalog/linter-query/linter-query-executor.d.ts +1 -1
- package/queries/catalog/linter-query/linter-query-executor.js +2 -2
- package/queries/catalog/linter-query/linter-query-format.d.ts +1 -1
- package/queries/catalog/linter-query/linter-query-format.js +16 -12
- package/queries/catalog/normalized-ast-query/normalized-ast-query-format.d.ts +1 -1
- package/queries/catalog/origin-query/origin-query-format.d.ts +1 -1
- package/queries/catalog/project-query/project-query-format.d.ts +1 -1
- package/queries/catalog/resolve-value-query/resolve-value-query-executor.d.ts +1 -1
- package/queries/catalog/resolve-value-query/resolve-value-query-executor.js +2 -2
- package/queries/catalog/resolve-value-query/resolve-value-query-format.d.ts +1 -1
- package/queries/catalog/search-query/search-query-executor.d.ts +1 -1
- package/queries/catalog/search-query/search-query-executor.js +2 -2
- package/queries/catalog/search-query/search-query-format.d.ts +1 -1
- package/queries/catalog/static-slice-query/static-slice-query-executor.d.ts +1 -1
- package/queries/catalog/static-slice-query/static-slice-query-executor.js +2 -2
- package/queries/catalog/static-slice-query/static-slice-query-format.d.ts +1 -1
- package/queries/query.d.ts +76 -16
- package/queries/query.js +2 -0
- package/r-bridge/lang-4.x/ast/parser/json/parser.d.ts +2 -1
- package/r-bridge/lang-4.x/ast/parser/json/parser.js +4 -2
- package/r-bridge/lang-4.x/convert-values.js +2 -1
- package/r-bridge/lang-4.x/tree-sitter/tree-sitter-executor.d.ts +3 -1
- package/r-bridge/lang-4.x/tree-sitter/tree-sitter-executor.js +4 -4
- package/r-bridge/lang-4.x/tree-sitter/tree-sitter-normalize.d.ts +1 -1
- package/r-bridge/lang-4.x/tree-sitter/tree-sitter-normalize.js +7 -5
- package/r-bridge/shell.d.ts +3 -2
- package/r-bridge/shell.js +4 -5
- package/search/flowr-search-builder.d.ts +6 -2
- package/search/flowr-search-builder.js +7 -0
- package/search/flowr-search-filters.d.ts +32 -8
- package/search/flowr-search-filters.js +42 -15
- package/search/flowr-search.d.ts +4 -0
- package/search/search-executor/search-enrichers.d.ts +7 -3
- package/search/search-executor/search-enrichers.js +29 -20
- package/search/search-executor/search-generators.js +1 -1
- package/search/search-executor/search-transformer.d.ts +2 -0
- package/search/search-executor/search-transformer.js +10 -1
- package/slicing/static/static-slicer.d.ts +1 -1
- package/slicing/static/static-slicer.js +2 -3
- package/statistics/statistics.d.ts +3 -1
- package/statistics/statistics.js +5 -4
- package/util/containers.d.ts +12 -9
- package/util/containers.js +12 -9
- package/util/files.d.ts +8 -2
- package/util/files.js +22 -4
- package/util/objects.d.ts +5 -4
- package/util/r-value.d.ts +23 -0
- package/util/r-value.js +113 -0
- package/util/range.d.ts +5 -1
- package/util/range.js +11 -3
- package/util/text/strings.d.ts +6 -0
- package/util/text/strings.js +35 -0
- package/util/version.js +1 -1
- package/linter/rules/1-deprecated-functions.d.ts +0 -34
- package/linter/rules/1-deprecated-functions.js +0 -54
- package/util/cfg/cfg.d.ts +0 -0
- package/util/cfg/cfg.js +0 -2
|
@@ -20,6 +20,7 @@ const assert_1 = require("../../util/assert");
|
|
|
20
20
|
const time_1 = require("../../util/text/time");
|
|
21
21
|
const tar_1 = require("tar");
|
|
22
22
|
const ansi_1 = require("../../util/text/ansi");
|
|
23
|
+
const config_1 = require("../../config");
|
|
23
24
|
function compressFolder(folder, target) {
|
|
24
25
|
return (0, tar_1.create)({
|
|
25
26
|
gzip: true,
|
|
@@ -35,7 +36,7 @@ function compressFolder(folder, target) {
|
|
|
35
36
|
console.error('Error during compression:', e);
|
|
36
37
|
});
|
|
37
38
|
}
|
|
38
|
-
async function getStatsForSingleFile(options) {
|
|
39
|
+
async function getStatsForSingleFile(options, config) {
|
|
39
40
|
if (options['no-ansi']) {
|
|
40
41
|
log_1.log.info('disabling ansi colors');
|
|
41
42
|
(0, ansi_1.setFormatter)(ansi_1.voidFormatter);
|
|
@@ -50,15 +51,15 @@ async function getStatsForSingleFile(options) {
|
|
|
50
51
|
}
|
|
51
52
|
// assume correct
|
|
52
53
|
const processedFeatures = new Set(options.features);
|
|
53
|
-
const shell = new shell_1.RShell();
|
|
54
|
+
const shell = new shell_1.RShell((0, config_1.getEngineConfig)(config, 'r-shell'));
|
|
54
55
|
(0, statistics_file_1.initFileProvider)(options['output-dir']);
|
|
55
56
|
await shell.obtainTmpDir();
|
|
56
|
-
const stats = await (0, statistics_1.extractUsageStatistics)(shell, () => { }, processedFeatures, (0, statistics_1.staticRequests)({ request: 'file', content: options.input }), options['root-dir']);
|
|
57
|
+
const stats = await (0, statistics_1.extractUsageStatistics)(shell, config, () => { }, processedFeatures, (0, statistics_1.staticRequests)({ request: 'file', content: options.input }), options['root-dir']);
|
|
57
58
|
// console.warn(`skipped ${stats.meta.failedRequests.length} requests due to errors (run with logs to get more info)`)
|
|
58
59
|
if (stats.outputs.size === 1) {
|
|
59
60
|
if (options['dump-json']) {
|
|
60
61
|
const [, output] = [...stats.outputs.entries()][0];
|
|
61
|
-
const cfg = (0, extract_cfg_1.extractCfg)(output.normalize, output.dataflow.graph);
|
|
62
|
+
const cfg = (0, extract_cfg_1.extractCfg)(output.normalize, config, output.dataflow.graph);
|
|
62
63
|
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
64
|
statistics_file_1.statisticsFileProvider.append('output-json', 'normalize', await (0, print_1.printStepResult)(_10_normalize_1.NORMALIZE, output.normalize, 2 /* StepOutputFormat.Json */));
|
|
64
65
|
statistics_file_1.statisticsFileProvider.append('output-json', 'dataflow', await (0, print_1.printStepResult)(_20_dataflow_1.STATIC_DATAFLOW, output.dataflow, 2 /* StepOutputFormat.Json */));
|
package/cli/slicer-app.js
CHANGED
|
@@ -14,6 +14,7 @@ const slicer_1 = require("../benchmark/slicer");
|
|
|
14
14
|
const print_1 = require("../benchmark/stats/print");
|
|
15
15
|
const magic_comments_1 = require("../reconstruct/auto-select/magic-comments");
|
|
16
16
|
const auto_select_defaults_1 = require("../reconstruct/auto-select/auto-select-defaults");
|
|
17
|
+
const config_1 = require("../config");
|
|
17
18
|
const options = (0, script_1.processCommandLineArgs)('slicer', ['input', 'criterion'], {
|
|
18
19
|
subtitle: 'Slice R code based on a given slicing criterion',
|
|
19
20
|
examples: [
|
|
@@ -28,9 +29,10 @@ async function getSlice() {
|
|
|
28
29
|
const slicer = new slicer_1.BenchmarkSlicer('r-shell');
|
|
29
30
|
(0, assert_1.guard)(options.input !== undefined, 'input must be given');
|
|
30
31
|
(0, assert_1.guard)(options.criterion !== undefined, 'a slicing criterion must be given');
|
|
32
|
+
const config = (0, config_1.getConfig)();
|
|
31
33
|
await slicer.init(options['input-is-text']
|
|
32
34
|
? { request: 'text', content: options.input.replaceAll('\\n', '\n') }
|
|
33
|
-
: { request: 'file', content: options.input }, options['no-magic-comments'] ? auto_select_defaults_1.doNotAutoSelect : (0, magic_comments_1.makeMagicCommentHandler)(auto_select_defaults_1.doNotAutoSelect));
|
|
35
|
+
: { request: 'file', content: options.input }, config, options['no-magic-comments'] ? auto_select_defaults_1.doNotAutoSelect : (0, magic_comments_1.makeMagicCommentHandler)(auto_select_defaults_1.doNotAutoSelect));
|
|
34
36
|
let mappedSlices = [];
|
|
35
37
|
let reconstruct = undefined;
|
|
36
38
|
const doSlicing = options.criterion.trim() !== '';
|
|
@@ -58,7 +60,7 @@ async function getSlice() {
|
|
|
58
60
|
const { stats, normalize, parse, tokenMap, dataflow } = slicer.finish();
|
|
59
61
|
const mappedCriteria = mappedSlices.map(c => ` ${c.criterion} => ${c.id} (${JSON.stringify(normalize.idMap.get(c.id)?.location)})`).join('\n');
|
|
60
62
|
log_1.log.info(`Mapped criteria:\n${mappedCriteria}`);
|
|
61
|
-
const sliceStatsAsString = (0, print_1.stats2string)(await (0, process_1.summarizeSlicerStats)(stats));
|
|
63
|
+
const sliceStatsAsString = (0, print_1.stats2string)(await (0, process_1.summarizeSlicerStats)(stats, undefined, (0, config_1.getEngineConfig)(config, 'r-shell')));
|
|
62
64
|
if (options.api) {
|
|
63
65
|
const output = {
|
|
64
66
|
tokenMap,
|
package/cli/statistics-app.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const script_1 = require("./common/script");
|
|
4
4
|
const statistics_core_1 = require("./script-core/statistics-core");
|
|
5
|
+
const config_1 = require("../config");
|
|
5
6
|
const scriptOptions = (0, script_1.processCommandLineArgs)('stats', [], {
|
|
6
7
|
subtitle: 'Given input files or folders, this will collect usage statistics for the given features and write them to a file',
|
|
7
8
|
examples: [
|
|
@@ -11,5 +12,5 @@ const scriptOptions = (0, script_1.processCommandLineArgs)('stats', [], {
|
|
|
11
12
|
'{bold --help}'
|
|
12
13
|
]
|
|
13
14
|
});
|
|
14
|
-
void (0, statistics_core_1.flowrScriptGetStats)(scriptOptions);
|
|
15
|
+
void (0, statistics_core_1.flowrScriptGetStats)(scriptOptions, (0, config_1.getConfig)());
|
|
15
16
|
//# sourceMappingURL=statistics-app.js.map
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const script_1 = require("./common/script");
|
|
4
4
|
const statistics_helper_core_1 = require("./script-core/statistics-helper-core");
|
|
5
|
+
const config_1 = require("../config");
|
|
5
6
|
const scriptOptions = (0, script_1.processCommandLineArgs)('stats-helper', [], {
|
|
6
7
|
subtitle: 'Given a single input file, this will collect usage statistics for the given features and write them to a file',
|
|
7
8
|
examples: [
|
|
@@ -9,5 +10,5 @@ const scriptOptions = (0, script_1.processCommandLineArgs)('stats-helper', [], {
|
|
|
9
10
|
'{bold --help}'
|
|
10
11
|
]
|
|
11
12
|
});
|
|
12
|
-
void (0, statistics_helper_core_1.getStatsForSingleFile)(scriptOptions);
|
|
13
|
+
void (0, statistics_helper_core_1.getStatsForSingleFile)(scriptOptions, (0, config_1.getConfig)());
|
|
13
14
|
//# sourceMappingURL=statistics-helper-app.js.map
|
package/config.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import type { MergeableRecord } from './util/objects';
|
|
|
2
2
|
import Joi from 'joi';
|
|
3
3
|
import type { BuiltInDefinitions } from './dataflow/environments/built-in-config';
|
|
4
4
|
import type { KnownParser } from './r-bridge/parser';
|
|
5
|
-
import type {
|
|
5
|
+
import type { DeepWritable } from 'ts-essentials';
|
|
6
6
|
export declare enum VariableResolve {
|
|
7
7
|
/** Don't resolve constants at all */
|
|
8
8
|
Disabled = "disabled",
|
|
@@ -47,7 +47,7 @@ export interface FlowrLaxSourcingOptions extends MergeableRecord {
|
|
|
47
47
|
/**
|
|
48
48
|
* Additionally search in these paths
|
|
49
49
|
*/
|
|
50
|
-
readonly searchPath:
|
|
50
|
+
readonly searchPath: string[];
|
|
51
51
|
/**
|
|
52
52
|
* Allow to drop the first or all parts of the sourced path,
|
|
53
53
|
* if it is relative.
|
|
@@ -77,7 +77,7 @@ export interface FlowrLaxSourcingOptions extends MergeableRecord {
|
|
|
77
77
|
* - `foo bar.R` (original name)
|
|
78
78
|
* - `main.R` (replaced with main.R)
|
|
79
79
|
* - `foo_bar.R` (replaced spaces)
|
|
80
|
-
* - `
|
|
80
|
+
* - `faa-bar.R` (replaced spaces and oo)
|
|
81
81
|
*/
|
|
82
82
|
readonly applyReplacements?: Record<string, string>[];
|
|
83
83
|
}
|
|
@@ -103,7 +103,7 @@ export interface FlowrConfigOptions extends MergeableRecord {
|
|
|
103
103
|
* The engines to use for interacting with R code. Currently, supports {@link TreeSitterEngineConfig} and {@link RShellEngineConfig}.
|
|
104
104
|
* An empty array means all available engines will be used.
|
|
105
105
|
*/
|
|
106
|
-
readonly engines:
|
|
106
|
+
readonly engines: EngineConfig[];
|
|
107
107
|
/**
|
|
108
108
|
* The default engine to use for interacting with R code. If this is undefined, an arbitrary engine from {@link engines} will be used.
|
|
109
109
|
*/
|
|
@@ -145,6 +145,37 @@ export interface FlowrConfigOptions extends MergeableRecord {
|
|
|
145
145
|
readonly threshold?: number;
|
|
146
146
|
};
|
|
147
147
|
};
|
|
148
|
+
/**
|
|
149
|
+
* Configuration options for abstract interpretation
|
|
150
|
+
*/
|
|
151
|
+
readonly abstractInterpretation: {
|
|
152
|
+
/**
|
|
153
|
+
* The configuration of the shape inference for data frames
|
|
154
|
+
*/
|
|
155
|
+
readonly dataFrame: {
|
|
156
|
+
/**
|
|
157
|
+
* The maximum number of columns names to infer for data frames before over-approximating the column names to top
|
|
158
|
+
*/
|
|
159
|
+
readonly maxColNames: number;
|
|
160
|
+
/**
|
|
161
|
+
* The threshold for the number of visitations of a node at which widening should be performed to ensure the termination of the fixpoint iteration
|
|
162
|
+
*/
|
|
163
|
+
readonly wideningThreshold: number;
|
|
164
|
+
/**
|
|
165
|
+
* Configuration options for reading data frame shapes from loaded external data files, such as CSV files
|
|
166
|
+
*/
|
|
167
|
+
readonly readLoadedData: {
|
|
168
|
+
/**
|
|
169
|
+
* Whether data frame shapes should be extracted from loaded external data files, such as CSV files
|
|
170
|
+
*/
|
|
171
|
+
readonly readExternalFiles: boolean;
|
|
172
|
+
/**
|
|
173
|
+
* The maximum number of lines to read when extracting data frame shapes from loaded files, such as CSV files
|
|
174
|
+
*/
|
|
175
|
+
readonly maxReadLines: number;
|
|
176
|
+
};
|
|
177
|
+
};
|
|
178
|
+
};
|
|
148
179
|
}
|
|
149
180
|
export interface TreeSitterEngineConfig extends MergeableRecord {
|
|
150
181
|
readonly type: 'tree-sitter';
|
|
@@ -174,12 +205,14 @@ export type KnownEngines = {
|
|
|
174
205
|
};
|
|
175
206
|
export declare const defaultConfigOptions: FlowrConfigOptions;
|
|
176
207
|
export declare const flowrConfigFileSchema: Joi.ObjectSchema<any>;
|
|
177
|
-
export declare function setConfigFile(file: string | undefined, workingDirectory?: string, forceLoad?: boolean): void;
|
|
178
208
|
export declare function parseConfig(jsonString: string): FlowrConfigOptions | undefined;
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
export declare function
|
|
209
|
+
/**
|
|
210
|
+
* Creates a new flowr config that has the updated values.
|
|
211
|
+
*/
|
|
212
|
+
export declare function amendConfig(config: FlowrConfigOptions, amendmentFunc: (config: DeepWritable<FlowrConfigOptions>) => FlowrConfigOptions): FlowrConfigOptions;
|
|
213
|
+
export declare function cloneConfig(config: FlowrConfigOptions): FlowrConfigOptions;
|
|
214
|
+
export declare function getConfig(configFile?: string, configWorkingDirectory?: string): FlowrConfigOptions;
|
|
215
|
+
export declare function getEngineConfig<T extends EngineConfig['type']>(config: FlowrConfigOptions, engine: T): EngineConfig & {
|
|
183
216
|
type: T;
|
|
184
217
|
} | undefined;
|
|
185
|
-
export declare function isOverPointerAnalysisThreshold(count: number): boolean;
|
|
218
|
+
export declare function isOverPointerAnalysisThreshold(config: FlowrConfigOptions, count: number): boolean;
|
package/config.js
CHANGED
|
@@ -4,10 +4,9 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.flowrConfigFileSchema = exports.defaultConfigOptions = exports.DropPathsOption = exports.InferWorkingDirectory = exports.VariableResolve = void 0;
|
|
7
|
-
exports.setConfigFile = setConfigFile;
|
|
8
7
|
exports.parseConfig = parseConfig;
|
|
9
|
-
exports.setConfig = setConfig;
|
|
10
8
|
exports.amendConfig = amendConfig;
|
|
9
|
+
exports.cloneConfig = cloneConfig;
|
|
11
10
|
exports.getConfig = getConfig;
|
|
12
11
|
exports.getEngineConfig = getEngineConfig;
|
|
13
12
|
exports.isOverPointerAnalysisThreshold = isOverPointerAnalysisThreshold;
|
|
@@ -82,6 +81,16 @@ exports.defaultConfigOptions = {
|
|
|
82
81
|
slicer: {
|
|
83
82
|
threshold: 50
|
|
84
83
|
}
|
|
84
|
+
},
|
|
85
|
+
abstractInterpretation: {
|
|
86
|
+
dataFrame: {
|
|
87
|
+
maxColNames: 50,
|
|
88
|
+
wideningThreshold: 4,
|
|
89
|
+
readLoadedData: {
|
|
90
|
+
readExternalFiles: true,
|
|
91
|
+
maxReadLines: 1e6
|
|
92
|
+
}
|
|
93
|
+
}
|
|
85
94
|
}
|
|
86
95
|
};
|
|
87
96
|
exports.flowrConfigFileSchema = joi_1.default.object({
|
|
@@ -121,21 +130,18 @@ exports.flowrConfigFileSchema = joi_1.default.object({
|
|
|
121
130
|
slicer: joi_1.default.object({
|
|
122
131
|
threshold: joi_1.default.number().optional().description('The maximum number of iterations to perform on a single function call during slicing.')
|
|
123
132
|
}).optional().description('The configuration for the slicer.')
|
|
124
|
-
}).description('How to resolve constants, constraints, cells, ...')
|
|
133
|
+
}).description('How to resolve constants, constraints, cells, ...'),
|
|
134
|
+
abstractInterpretation: joi_1.default.object({
|
|
135
|
+
dataFrame: joi_1.default.object({
|
|
136
|
+
maxColNames: joi_1.default.number().min(0).description('The maximum number of columns names to infer for data frames before over-approximating the column names to top.'),
|
|
137
|
+
wideningThreshold: joi_1.default.number().min(1).description('The threshold for the number of visitations of a node at which widening should be performed to ensure the termination of the fixpoint iteration.'),
|
|
138
|
+
readLoadedData: joi_1.default.object({
|
|
139
|
+
readExternalFiles: joi_1.default.boolean().description('Whether data frame shapes should be extracted from loaded external files, such as CSV files.'),
|
|
140
|
+
maxReadLines: joi_1.default.number().min(1).description('The maximum number of lines to read when extracting data frame shapes from loaded files, such as CSV files.')
|
|
141
|
+
}).description('Configuration options for reading data frame shapes from loaded external data files, such as CSV files.')
|
|
142
|
+
}).description('The configuration of the shape inference for data frames.')
|
|
143
|
+
}).description('The configuration options for abstract interpretation.')
|
|
125
144
|
}).description('The configuration file format for flowR.');
|
|
126
|
-
// we don't load from a config file at all by default unless setConfigFile is called
|
|
127
|
-
let configFile = undefined;
|
|
128
|
-
let configWorkingDirectory = process.cwd();
|
|
129
|
-
let currentConfig = undefined;
|
|
130
|
-
function setConfigFile(file, workingDirectory = process.cwd(), forceLoad = false) {
|
|
131
|
-
configFile = file;
|
|
132
|
-
configWorkingDirectory = workingDirectory;
|
|
133
|
-
// reset the config so it gets reloaded
|
|
134
|
-
currentConfig = undefined;
|
|
135
|
-
if (forceLoad) {
|
|
136
|
-
getConfig();
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
145
|
function parseConfig(jsonString) {
|
|
140
146
|
try {
|
|
141
147
|
const parsed = JSON.parse(jsonString);
|
|
@@ -153,46 +159,44 @@ function parseConfig(jsonString) {
|
|
|
153
159
|
log_1.log.error(`Failed to parse config ${jsonString}: ${e.message}`);
|
|
154
160
|
}
|
|
155
161
|
}
|
|
156
|
-
|
|
157
|
-
|
|
162
|
+
/**
|
|
163
|
+
* Creates a new flowr config that has the updated values.
|
|
164
|
+
*/
|
|
165
|
+
function amendConfig(config, amendmentFunc) {
|
|
166
|
+
return amendmentFunc(cloneConfig(config));
|
|
158
167
|
}
|
|
159
|
-
function
|
|
160
|
-
|
|
161
|
-
log_1.log.trace(`Amending config with ${JSON.stringify(amendment)}, resulting in ${JSON.stringify(getConfig())}}`);
|
|
168
|
+
function cloneConfig(config) {
|
|
169
|
+
return JSON.parse(JSON.stringify(config));
|
|
162
170
|
}
|
|
163
|
-
function getConfig() {
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
log_1.log.error(`Failed to load config: ${e.message}`);
|
|
171
|
-
setConfig(exports.defaultConfigOptions);
|
|
172
|
-
}
|
|
171
|
+
function getConfig(configFile, configWorkingDirectory = process.cwd()) {
|
|
172
|
+
try {
|
|
173
|
+
return loadConfigFromFile(configFile, configWorkingDirectory);
|
|
174
|
+
}
|
|
175
|
+
catch (e) {
|
|
176
|
+
log_1.log.error(`Failed to load config: ${e.message}`);
|
|
177
|
+
return exports.defaultConfigOptions;
|
|
173
178
|
}
|
|
174
|
-
return currentConfig;
|
|
175
179
|
}
|
|
176
|
-
function getEngineConfig(engine) {
|
|
177
|
-
const
|
|
178
|
-
if (!
|
|
180
|
+
function getEngineConfig(config, engine) {
|
|
181
|
+
const engines = config.engines;
|
|
182
|
+
if (!engines.length) {
|
|
179
183
|
return defaultEngineConfigs[engine];
|
|
180
184
|
}
|
|
181
185
|
else {
|
|
182
|
-
return
|
|
186
|
+
return engines.find(e => e.type == engine);
|
|
183
187
|
}
|
|
184
188
|
}
|
|
185
|
-
function getPointerAnalysisThreshold() {
|
|
186
|
-
const
|
|
187
|
-
if (typeof
|
|
188
|
-
return
|
|
189
|
+
function getPointerAnalysisThreshold(config) {
|
|
190
|
+
const pointerTracking = config.solver.pointerTracking;
|
|
191
|
+
if (typeof pointerTracking === 'object') {
|
|
192
|
+
return pointerTracking.maxIndexCount;
|
|
189
193
|
}
|
|
190
194
|
else {
|
|
191
|
-
return
|
|
195
|
+
return pointerTracking ? 'unlimited' : 'disabled';
|
|
192
196
|
}
|
|
193
197
|
}
|
|
194
|
-
function isOverPointerAnalysisThreshold(count) {
|
|
195
|
-
const threshold = getPointerAnalysisThreshold();
|
|
198
|
+
function isOverPointerAnalysisThreshold(config, count) {
|
|
199
|
+
const threshold = getPointerAnalysisThreshold(config);
|
|
196
200
|
return threshold !== 'unlimited' && (threshold === 'disabled' || count > threshold);
|
|
197
201
|
}
|
|
198
202
|
function loadConfigFromFile(configFile, workingDirectory) {
|
|
@@ -10,6 +10,7 @@ const general_1 = require("../dataflow/eval/values/general");
|
|
|
10
10
|
const r_value_1 = require("../dataflow/eval/values/r-value");
|
|
11
11
|
class CfgConditionalDeadCodeRemoval extends semantic_cfg_guided_visitor_1.SemanticCfgGuidedVisitor {
|
|
12
12
|
cachedConditions = new Map();
|
|
13
|
+
cachedStatements = new Map();
|
|
13
14
|
getValue(id) {
|
|
14
15
|
const has = this.cachedConditions.get(id);
|
|
15
16
|
if (has) {
|
|
@@ -18,6 +19,14 @@ class CfgConditionalDeadCodeRemoval extends semantic_cfg_guided_visitor_1.Semant
|
|
|
18
19
|
this.visitNode(id);
|
|
19
20
|
return this.cachedConditions.get(id) ?? logic_1.Ternary.Maybe;
|
|
20
21
|
}
|
|
22
|
+
isUnconditionalJump(id) {
|
|
23
|
+
const has = this.cachedStatements.get(id);
|
|
24
|
+
if (has) {
|
|
25
|
+
return has;
|
|
26
|
+
}
|
|
27
|
+
this.visitNode(id);
|
|
28
|
+
return this.cachedStatements.get(id) ?? false;
|
|
29
|
+
}
|
|
21
30
|
unableToCalculateValue(id) {
|
|
22
31
|
this.cachedConditions.set(id, logic_1.Ternary.Maybe);
|
|
23
32
|
}
|
|
@@ -36,11 +45,16 @@ class CfgConditionalDeadCodeRemoval extends semantic_cfg_guided_visitor_1.Semant
|
|
|
36
45
|
this.config.controlFlow.graph.removeEdge(from, target);
|
|
37
46
|
}
|
|
38
47
|
}
|
|
48
|
+
else if (edge.label === 0 /* CfgEdgeType.Fd */) {
|
|
49
|
+
if (this.isUnconditionalJump(target)) {
|
|
50
|
+
this.config.controlFlow.graph.removeEdge(from, target);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
39
53
|
}
|
|
40
54
|
}
|
|
41
55
|
}
|
|
42
56
|
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 }));
|
|
57
|
+
const values = (0, general_1.valueSetGuard)((0, alias_tracking_1.resolveIdToValue)(valueId, { graph: this.config.dfg, full: true, idMap: this.config.normalizedAst.idMap, resolve: this.config.flowrConfig.solver.variables }));
|
|
44
58
|
if (values === undefined || values.elements.length !== 1 || values.elements[0].type != 'logical' || !(0, r_value_1.isValue)(values.elements[0].value)) {
|
|
45
59
|
this.unableToCalculateValue(id);
|
|
46
60
|
return;
|
|
@@ -56,12 +70,40 @@ class CfgConditionalDeadCodeRemoval extends semantic_cfg_guided_visitor_1.Semant
|
|
|
56
70
|
}
|
|
57
71
|
this.handleValuesFor(id, typeof data.condition === 'object' ? data.condition.nodeId : data.condition);
|
|
58
72
|
}
|
|
73
|
+
getBoolArgValue(data) {
|
|
74
|
+
if (data.call.args.length !== 1 || data.call.args[0] === r_function_call_1.EmptyArgument) {
|
|
75
|
+
return undefined;
|
|
76
|
+
}
|
|
77
|
+
const values = (0, general_1.valueSetGuard)((0, alias_tracking_1.resolveIdToValue)(data.call.args[0].nodeId, { graph: this.config.dfg, full: true, idMap: this.config.normalizedAst.idMap, resolve: this.config.flowrConfig.solver.variables }));
|
|
78
|
+
if (values === undefined || values.elements.length !== 1 || values.elements[0].type != 'logical' || !(0, r_value_1.isValue)(values.elements[0].value)) {
|
|
79
|
+
return undefined;
|
|
80
|
+
}
|
|
81
|
+
return Boolean(values.elements[0].value);
|
|
82
|
+
}
|
|
83
|
+
handleFunctionCall(data) {
|
|
84
|
+
switch (data.call.origin[0]) {
|
|
85
|
+
case 'builtin:return':
|
|
86
|
+
case 'builtin:stop':
|
|
87
|
+
this.cachedStatements.set(data.call.id, true);
|
|
88
|
+
break;
|
|
89
|
+
case 'builtin:stopifnot': {
|
|
90
|
+
const arg = this.getBoolArgValue(data);
|
|
91
|
+
if (arg !== undefined) {
|
|
92
|
+
this.cachedStatements.set(data.call.id, !arg);
|
|
93
|
+
}
|
|
94
|
+
break;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
59
98
|
onIfThenElseCall(data) {
|
|
60
99
|
this.handleWithCondition(data);
|
|
61
100
|
}
|
|
62
101
|
onWhileLoopCall(data) {
|
|
63
102
|
this.handleWithCondition(data);
|
|
64
103
|
}
|
|
104
|
+
onDefaultFunctionCall(data) {
|
|
105
|
+
this.handleFunctionCall(data);
|
|
106
|
+
}
|
|
65
107
|
}
|
|
66
108
|
/** Breaks unsatisfiable control dependencies */
|
|
67
109
|
function cfgAnalyzeDeadCode(cfg, info) {
|
|
@@ -73,7 +115,8 @@ function cfgAnalyzeDeadCode(cfg, info) {
|
|
|
73
115
|
controlFlow: cfg,
|
|
74
116
|
normalizedAst: info.ast,
|
|
75
117
|
dfg: info.dfg,
|
|
76
|
-
|
|
118
|
+
flowrConfig: info.config,
|
|
119
|
+
defaultVisitingOrder: 'forward',
|
|
77
120
|
});
|
|
78
121
|
visitor.start();
|
|
79
122
|
return cfg;
|
|
@@ -2,9 +2,11 @@ import type { ControlFlowInformation } from './control-flow-graph';
|
|
|
2
2
|
import type { NormalizedAst } from '../r-bridge/lang-4.x/ast/model/processing/decorate';
|
|
3
3
|
import type { DataflowGraph } from '../dataflow/graph/graph';
|
|
4
4
|
import { cfgAnalyzeDeadCode } from './cfg-dead-code';
|
|
5
|
+
import type { FlowrConfigOptions } from '../config';
|
|
5
6
|
export interface CfgPassInfo {
|
|
6
7
|
ast?: NormalizedAst;
|
|
7
8
|
dfg?: DataflowGraph;
|
|
9
|
+
config: FlowrConfigOptions;
|
|
8
10
|
}
|
|
9
11
|
export type CfgSimplificationPass = (cfg: ControlFlowInformation, info: CfgPassInfo) => ControlFlowInformation;
|
|
10
12
|
export declare const CfgSimplificationPasses: {
|
|
@@ -67,6 +67,8 @@ 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;
|
|
71
|
+
export declare function getVertexRootId(vertex: CfgSimpleVertex): NodeId;
|
|
70
72
|
interface CfgFlowDependencyEdge extends MergeableRecord {
|
|
71
73
|
label: CfgEdgeType.Fd;
|
|
72
74
|
}
|
|
@@ -3,6 +3,8 @@ 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;
|
|
7
|
+
exports.getVertexRootId = getVertexRootId;
|
|
6
8
|
exports.emptyControlFlowInformation = emptyControlFlowInformation;
|
|
7
9
|
const assert_1 = require("../util/assert");
|
|
8
10
|
var CfgVertexType;
|
|
@@ -43,6 +45,12 @@ function equalVertex(a, b) {
|
|
|
43
45
|
}
|
|
44
46
|
return true;
|
|
45
47
|
}
|
|
48
|
+
function isMarkerVertex(vertex) {
|
|
49
|
+
return vertex.type === CfgVertexType.MidMarker || vertex.type === CfgVertexType.EndMarker;
|
|
50
|
+
}
|
|
51
|
+
function getVertexRootId(vertex) {
|
|
52
|
+
return isMarkerVertex(vertex) ? vertex.root : vertex.id;
|
|
53
|
+
}
|
|
46
54
|
/**
|
|
47
55
|
* This class represents the control flow graph of an R program.
|
|
48
56
|
* The control flow may be hierarchical when confronted with function definitions (see {@link CfgSimpleVertex} and {@link CFG#rootVertexIds|rootVertexIds()}).
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
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
3
|
import type { DataflowGraphVertexArgument, DataflowGraphVertexFunctionCall, DataflowGraphVertexFunctionDefinition, DataflowGraphVertexUse, DataflowGraphVertexValue, DataflowGraphVertexVariableDefinition } from '../dataflow/graph/vertex';
|
|
4
4
|
import type { BasicCfgGuidedVisitorConfiguration } from './basic-cfg-guided-visitor';
|
|
@@ -6,6 +6,7 @@ import { BasicCfgGuidedVisitor } from './basic-cfg-guided-visitor';
|
|
|
6
6
|
import type { DataflowGraph } from '../dataflow/graph/graph';
|
|
7
7
|
export interface DataflowCfgGuidedVisitorConfiguration<ControlFlow extends ControlFlowInformation = ControlFlowInformation, Dfg extends DataflowGraph = DataflowGraph> extends BasicCfgGuidedVisitorConfiguration<ControlFlow> {
|
|
8
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.
|
|
@@ -19,11 +20,12 @@ export declare class DataflowAwareCfgGuidedVisitor<ControlFlow extends ControlFl
|
|
|
19
20
|
protected getDataflowGraph(id: NodeId): DataflowGraphVertexArgument | undefined;
|
|
20
21
|
protected onStatementNode(node: CfgStatementVertex): void;
|
|
21
22
|
protected onExpressionNode(node: CfgExpressionVertex): void;
|
|
22
|
-
|
|
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:
|
|
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");
|
|
@@ -18,14 +19,24 @@ class DataflowAwareCfgGuidedVisitor extends basic_cfg_guided_visitor_1.BasicCfgG
|
|
|
18
19
|
}
|
|
19
20
|
onStatementNode(node) {
|
|
20
21
|
super.onStatementNode(node);
|
|
21
|
-
this.
|
|
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.
|
|
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
|
-
|
|
28
|
-
const dfgVertex = this.getDataflowGraph(
|
|
38
|
+
visitDataflowNode(node) {
|
|
39
|
+
const dfgVertex = this.getDataflowGraph((0, control_flow_graph_1.getVertexRootId)(node));
|
|
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
|
|
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 & ParentInformation>, 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
|
|
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), { ast, dfg: graph }, 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!
|
|
@@ -14,7 +14,9 @@ import type { NoInfo, RNode } from '../r-bridge/lang-4.x/ast/model/model';
|
|
|
14
14
|
import type { RSymbol } from '../r-bridge/lang-4.x/ast/model/nodes/r-symbol';
|
|
15
15
|
import type { BuiltInProcessorMapper } from '../dataflow/environments/built-in';
|
|
16
16
|
import type { RExpressionList } from '../r-bridge/lang-4.x/ast/model/nodes/r-expression-list';
|
|
17
|
+
import type { FlowrConfigOptions } from '../config';
|
|
17
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;
|
|
18
20
|
}
|
|
19
21
|
/**
|
|
20
22
|
* This visitor extends on the {@link DataflowAwareCfgGuidedVisitor} by dispatching visitors for separate function calls as well,
|
|
@@ -43,7 +45,7 @@ export declare class SemanticCfgGuidedVisitor<OtherInfo = NoInfo, ControlFlow ex
|
|
|
43
45
|
/**
|
|
44
46
|
* A helper function to get the normalized AST node for the given id or fail if it does not exist.
|
|
45
47
|
*/
|
|
46
|
-
protected getNormalizedAst(id: NodeId): RNode<OtherInfo & ParentInformation> | undefined;
|
|
48
|
+
protected getNormalizedAst(id: NodeId | undefined): RNode<OtherInfo & ParentInformation> | undefined;
|
|
47
49
|
/**
|
|
48
50
|
* See {@link DataflowAwareCfgGuidedVisitor#visitValue} for the base implementation.
|
|
49
51
|
* This now dispatches the value to the appropriate event handler based on its type.
|
|
@@ -126,7 +128,11 @@ export declare class SemanticCfgGuidedVisitor<OtherInfo = NoInfo, ControlFlow ex
|
|
|
126
128
|
* A helper function to request the {@link getOriginInDfg|origins} of the given node.
|
|
127
129
|
*/
|
|
128
130
|
protected getOrigins(id: NodeId): Origin[] | undefined;
|
|
129
|
-
/**
|
|
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
|
+
*/
|
|
130
136
|
protected onNullConstant(_data: {
|
|
131
137
|
vertex: DataflowGraphVertexValue;
|
|
132
138
|
node: RSymbol<OtherInfo & ParentInformation, 'NULL'>;
|
|
@@ -158,6 +164,18 @@ export declare class SemanticCfgGuidedVisitor<OtherInfo = NoInfo, ControlFlow ex
|
|
|
158
164
|
vertex: DataflowGraphVertexValue;
|
|
159
165
|
node: RLogical;
|
|
160
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;
|
|
161
179
|
/**
|
|
162
180
|
* Called for every variable that is read within the program.
|
|
163
181
|
* You can use {@link getOrigins} to get the origins of the variable.
|