@eagleoutice/flowr 2.6.3 → 2.7.2
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 +22 -22
- package/abstract-interpretation/absint-visitor.d.ts +160 -0
- package/abstract-interpretation/absint-visitor.js +279 -0
- package/abstract-interpretation/data-frame/dataframe-domain.d.ts +4 -7
- package/abstract-interpretation/data-frame/dataframe-domain.js +26 -16
- package/abstract-interpretation/data-frame/mappers/access-mapper.d.ts +6 -4
- package/abstract-interpretation/data-frame/mappers/access-mapper.js +11 -14
- package/abstract-interpretation/data-frame/mappers/arguments.d.ts +10 -9
- package/abstract-interpretation/data-frame/mappers/arguments.js +8 -5
- package/abstract-interpretation/data-frame/mappers/function-mapper.d.ts +18 -18
- package/abstract-interpretation/data-frame/mappers/function-mapper.js +53 -58
- package/abstract-interpretation/data-frame/mappers/replacement-mapper.d.ts +7 -5
- package/abstract-interpretation/data-frame/mappers/replacement-mapper.js +26 -29
- package/abstract-interpretation/data-frame/semantics.js +48 -44
- package/abstract-interpretation/data-frame/shape-inference.d.ts +52 -28
- package/abstract-interpretation/data-frame/shape-inference.js +67 -90
- package/abstract-interpretation/domains/abstract-domain.d.ts +1 -0
- package/abstract-interpretation/domains/abstract-domain.js +3 -2
- package/abstract-interpretation/domains/bounded-set-domain.d.ts +2 -2
- package/abstract-interpretation/domains/bounded-set-domain.js +1 -1
- package/abstract-interpretation/domains/interval-domain.d.ts +4 -4
- package/abstract-interpretation/domains/interval-domain.js +3 -6
- package/abstract-interpretation/domains/lattice.d.ts +2 -0
- package/abstract-interpretation/domains/lattice.js +3 -1
- package/abstract-interpretation/domains/positive-interval-domain.d.ts +1 -1
- package/abstract-interpretation/domains/positive-interval-domain.js +1 -1
- package/abstract-interpretation/domains/satisfiable-domain.d.ts +2 -2
- package/abstract-interpretation/domains/satisfiable-domain.js +2 -2
- package/abstract-interpretation/domains/set-range-domain.d.ts +104 -0
- package/abstract-interpretation/domains/set-range-domain.js +406 -0
- package/abstract-interpretation/domains/set-upper-bound-domain.d.ts +2 -2
- package/abstract-interpretation/domains/set-upper-bound-domain.js +2 -2
- package/abstract-interpretation/domains/singleton-domain.d.ts +2 -2
- package/abstract-interpretation/domains/singleton-domain.js +2 -2
- package/benchmark/slicer.d.ts +2 -1
- package/benchmark/slicer.js +50 -29
- package/benchmark/stats/print.js +8 -5
- package/benchmark/stats/stats.d.ts +3 -2
- package/benchmark/summarizer/data.d.ts +11 -8
- package/benchmark/summarizer/first-phase/process.js +11 -8
- package/benchmark/summarizer/second-phase/process.js +24 -18
- package/cli/common/options.d.ts +431 -8
- package/cli/common/options.js +1 -1
- package/cli/common/scripts-info.d.ts +431 -7
- package/cli/flowr-main-options.d.ts +102 -2
- package/cli/flowr.d.ts +102 -2
- package/cli/repl/commands/repl-commands.d.ts +25 -0
- package/cli/repl/commands/repl-query.js +17 -5
- package/cli/wiki.d.ts +13 -0
- package/cli/wiki.js +7 -2
- package/config.d.ts +4 -4
- package/config.js +1 -1
- package/control-flow/basic-cfg-guided-visitor.js +7 -8
- package/control-flow/cfg-dead-code.js +3 -2
- package/control-flow/control-flow-graph.d.ts +1 -1
- package/control-flow/semantic-cfg-guided-visitor.d.ts +1 -1
- package/control-flow/semantic-cfg-guided-visitor.js +1 -1
- package/control-flow/useless-loop.js +4 -2
- package/core/steps/all/static-slicing/00-slice.d.ts +3 -0
- package/core/steps/all/static-slicing/00-slice.js +2 -1
- package/core/steps/pipeline/default-pipelines.d.ts +42 -42
- package/dataflow/cluster.js +2 -2
- package/dataflow/environments/append.d.ts +5 -0
- package/dataflow/environments/append.js +6 -20
- package/dataflow/environments/built-in.d.ts +2 -1
- package/dataflow/environments/clone.d.ts +1 -1
- package/dataflow/environments/clone.js +3 -27
- package/dataflow/environments/define.d.ts +7 -3
- package/dataflow/environments/define.js +9 -56
- package/dataflow/environments/diff.js +1 -1
- package/dataflow/environments/environment.d.ts +48 -28
- package/dataflow/environments/environment.js +187 -62
- package/dataflow/environments/overwrite.js +2 -45
- package/dataflow/environments/reference-to-maybe.d.ts +13 -0
- package/dataflow/environments/reference-to-maybe.js +54 -0
- package/dataflow/environments/resolve-by-name.d.ts +6 -1
- package/dataflow/environments/resolve-by-name.js +56 -4
- package/dataflow/environments/scoping.d.ts +2 -2
- package/dataflow/environments/scoping.js +7 -7
- package/dataflow/eval/resolve/alias-tracking.d.ts +10 -4
- package/dataflow/eval/resolve/alias-tracking.js +16 -14
- package/dataflow/eval/resolve/resolve-argument.d.ts +2 -1
- package/dataflow/eval/resolve/resolve-argument.js +8 -8
- package/dataflow/eval/resolve/resolve.d.ts +13 -11
- package/dataflow/eval/resolve/resolve.js +16 -15
- package/dataflow/extractor.js +1 -7
- package/dataflow/fn/higher-order-function.d.ts +2 -1
- package/dataflow/fn/higher-order-function.js +4 -4
- package/dataflow/graph/dataflowgraph-builder.d.ts +9 -5
- package/dataflow/graph/dataflowgraph-builder.js +21 -11
- package/dataflow/graph/diff-dataflow-graph.js +2 -2
- package/dataflow/graph/graph.d.ts +10 -2
- package/dataflow/graph/graph.js +41 -12
- package/dataflow/graph/invert-dfg.d.ts +3 -2
- package/dataflow/graph/invert-dfg.js +3 -3
- package/dataflow/graph/resolve-graph.d.ts +2 -1
- package/dataflow/graph/resolve-graph.js +2 -2
- package/dataflow/graph/vertex.d.ts +3 -3
- package/dataflow/graph/vertex.js +3 -3
- package/dataflow/info.d.ts +1 -1
- package/dataflow/internal/linker.d.ts +2 -0
- package/dataflow/internal/linker.js +13 -19
- package/dataflow/internal/process/functions/call/argument/unpack-argument.d.ts +7 -1
- package/dataflow/internal/process/functions/call/argument/unpack-argument.js +12 -3
- package/dataflow/internal/process/functions/call/built-in/built-in-access.js +3 -3
- package/dataflow/internal/process/functions/call/built-in/built-in-apply.js +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-assignment.d.ts +3 -1
- package/dataflow/internal/process/functions/call/built-in/built-in-assignment.js +3 -3
- package/dataflow/internal/process/functions/call/built-in/built-in-eval.js +9 -9
- package/dataflow/internal/process/functions/call/built-in/built-in-expression-list.js +9 -7
- package/dataflow/internal/process/functions/call/built-in/built-in-for-loop.js +3 -3
- package/dataflow/internal/process/functions/call/built-in/built-in-function-definition.d.ts +2 -1
- package/dataflow/internal/process/functions/call/built-in/built-in-function-definition.js +9 -13
- package/dataflow/internal/process/functions/call/built-in/built-in-get.js +1 -1
- package/dataflow/internal/process/functions/call/built-in/built-in-if-then-else.d.ts +3 -1
- package/dataflow/internal/process/functions/call/built-in/built-in-if-then-else.js +8 -6
- package/dataflow/internal/process/functions/call/built-in/built-in-library.js +1 -1
- package/dataflow/internal/process/functions/call/built-in/built-in-pipe.js +1 -1
- package/dataflow/internal/process/functions/call/built-in/built-in-repeat-loop.js +1 -1
- package/dataflow/internal/process/functions/call/built-in/built-in-replacement.js +3 -3
- package/dataflow/internal/process/functions/call/built-in/built-in-rm.js +6 -4
- package/dataflow/internal/process/functions/call/built-in/built-in-source.js +1 -1
- package/dataflow/internal/process/functions/call/built-in/built-in-while-loop.js +5 -5
- package/dataflow/internal/process/functions/call/common.js +2 -3
- package/dataflow/internal/process/functions/call/known-call-handling.js +1 -1
- package/dataflow/internal/process/functions/call/unnamed-call-handling.js +1 -1
- package/dataflow/internal/process/functions/process-argument.js +1 -1
- package/dataflow/internal/process/process-symbol.js +1 -1
- package/dataflow/internal/process/process-value.d.ts +1 -1
- package/dataflow/internal/process/process-value.js +7 -7
- package/dataflow/processor.d.ts +1 -5
- package/documentation/doc-capabilities.d.ts +1 -1
- package/documentation/doc-readme.d.ts +1 -1
- package/documentation/doc-util/doc-cfg.js +1 -1
- package/documentation/doc-util/doc-cli-option.d.ts +6 -6
- package/documentation/doc-util/doc-cli-option.js +3 -3
- package/documentation/doc-util/doc-dfg.d.ts +1 -1
- package/documentation/doc-util/doc-dfg.js +3 -2
- package/documentation/doc-util/doc-files.d.ts +3 -0
- package/documentation/doc-util/doc-files.js +4 -1
- package/documentation/doc-util/doc-normalized-ast.js +5 -4
- package/documentation/doc-util/doc-types.d.ts +1 -1
- package/documentation/doc-util/doc-types.js +2 -2
- package/documentation/issue-linting-rule.d.ts +1 -1
- package/documentation/wiki-analyzer.d.ts +1 -1
- package/documentation/wiki-analyzer.js +14 -1
- package/documentation/wiki-cfg.d.ts +1 -1
- package/documentation/wiki-core.d.ts +1 -1
- package/documentation/wiki-dataflow-graph.d.ts +1 -1
- package/documentation/wiki-dataflow-graph.js +10 -11
- package/documentation/wiki-engine.d.ts +1 -1
- package/documentation/wiki-engine.js +9 -10
- package/documentation/wiki-faq.d.ts +1 -1
- package/documentation/wiki-faq.js +0 -1
- package/documentation/wiki-interface.d.ts +1 -1
- package/documentation/wiki-interface.js +12 -13
- package/documentation/wiki-linter.d.ts +1 -1
- package/documentation/wiki-linter.js +1 -1
- package/documentation/wiki-linting-and-testing.d.ts +1 -1
- package/documentation/wiki-mk/doc-context.d.ts +54 -1
- package/documentation/wiki-mk/doc-context.js +17 -0
- package/documentation/wiki-mk/doc-maker.d.ts +5 -5
- package/documentation/wiki-mk/doc-maker.js +5 -2
- package/documentation/wiki-normalized-ast.d.ts +1 -1
- package/documentation/wiki-onboarding.d.ts +1 -1
- package/documentation/wiki-overview.d.ts +9 -0
- package/documentation/wiki-overview.js +248 -0
- package/documentation/wiki-query.d.ts +1 -1
- package/documentation/wiki-query.js +17 -1
- package/documentation/wiki-search.d.ts +1 -1
- package/documentation/wiki-setup.d.ts +9 -0
- package/documentation/wiki-setup.js +122 -0
- package/linter/linter-rules.d.ts +2 -2
- package/linter/rules/absolute-path.js +4 -4
- package/linter/rules/dataframe-access-validation.d.ts +2 -2
- package/linter/rules/dataframe-access-validation.js +9 -11
- package/linter/rules/function-finder-util.d.ts +2 -2
- package/linter/rules/function-finder-util.js +1 -1
- package/linter/rules/network-functions.js +1 -1
- package/linter/rules/seeded-randomness.d.ts +1 -1
- package/linter/rules/seeded-randomness.js +5 -5
- package/linter/rules/unused-definition.js +1 -1
- package/package.json +1 -2
- package/project/context/flowr-analyzer-context.d.ts +11 -0
- package/project/context/flowr-analyzer-context.js +3 -0
- package/project/context/flowr-analyzer-environment-context.d.ts +47 -0
- package/project/context/flowr-analyzer-environment-context.js +50 -0
- package/project/context/flowr-analyzer-files-context.d.ts +9 -1
- package/project/context/flowr-analyzer-files-context.js +4 -0
- package/project/context/flowr-file.d.ts +2 -0
- package/project/context/flowr-file.js +2 -0
- package/project/plugins/file-plugins/{flowr-description-file.d.ts → files/flowr-description-file.d.ts} +1 -1
- package/project/plugins/file-plugins/files/flowr-description-file.js +75 -0
- package/project/plugins/file-plugins/files/flowr-news-file.d.ts +27 -0
- package/project/plugins/file-plugins/files/flowr-news-file.js +152 -0
- package/project/plugins/file-plugins/flowr-analyzer-description-file-plugin.d.ts +1 -1
- package/project/plugins/file-plugins/flowr-analyzer-description-file-plugin.js +1 -1
- package/project/plugins/file-plugins/flowr-analyzer-news-file-plugin.d.ts +23 -0
- package/project/plugins/file-plugins/flowr-analyzer-news-file-plugin.js +35 -0
- package/project/plugins/file-plugins/notebooks/flowr-analyzer-jupyter-file-plugin.d.ts +1 -1
- package/project/plugins/file-plugins/notebooks/flowr-analyzer-jupyter-file-plugin.js +1 -1
- package/project/plugins/file-plugins/notebooks/flowr-analyzer-qmd-file-plugin.d.ts +1 -1
- package/project/plugins/file-plugins/notebooks/flowr-analyzer-qmd-file-plugin.js +1 -1
- package/project/plugins/file-plugins/notebooks/flowr-analyzer-rmd-file-plugin.d.ts +1 -1
- package/project/plugins/file-plugins/notebooks/flowr-analyzer-rmd-file-plugin.js +1 -1
- package/project/plugins/flowr-analyzer-plugin-defaults.js +2 -0
- package/project/plugins/plugin-registry.d.ts +2 -1
- package/project/plugins/plugin-registry.js +2 -0
- package/project/plugins/project-discovery/flowr-analyzer-project-discovery-plugin.js +7 -1
- package/queries/catalog/call-context-query/call-context-query-executor.js +1 -4
- package/queries/catalog/control-flow-query/control-flow-query-format.js +3 -2
- package/queries/catalog/dataflow-lens-query/dataflow-lens-query-executor.js +1 -1
- package/queries/catalog/dependencies-query/dependencies-query-executor.js +4 -4
- package/queries/catalog/df-shape-query/df-shape-query-executor.d.ts +1 -1
- package/queries/catalog/df-shape-query/df-shape-query-executor.js +5 -3
- package/queries/catalog/df-shape-query/df-shape-query-format.d.ts +4 -4
- package/queries/catalog/df-shape-query/df-shape-query-format.js +2 -2
- package/queries/catalog/files-query/files-query-executor.d.ts +6 -0
- package/queries/catalog/files-query/files-query-executor.js +49 -0
- package/queries/catalog/files-query/files-query-format.d.ts +36 -0
- package/queries/catalog/files-query/files-query-format.js +114 -0
- package/queries/catalog/inspect-higher-order-query/inspect-higher-order-query-executor.js +3 -3
- package/queries/catalog/linter-query/linter-query-format.js +1 -1
- package/queries/catalog/resolve-value-query/resolve-value-query-executor.js +1 -1
- package/queries/catalog/static-slice-query/static-slice-query-executor.js +1 -1
- package/queries/query.d.ts +10 -1
- package/queries/query.js +3 -1
- package/r-bridge/lang-4.x/ast/model/model.d.ts +1 -1
- package/r-bridge/lang-4.x/ast/model/processing/decorate.js +8 -8
- package/r-bridge/lang-4.x/ast/model/processing/role.d.ts +8 -8
- package/r-bridge/lang-4.x/ast/parser/main/internal/functions/normalize-parameter.js +0 -1
- package/r-bridge/lang-4.x/tree-sitter/tree-sitter-normalize.js +0 -1
- package/slicing/static/slice-call.d.ts +3 -2
- package/slicing/static/slice-call.js +4 -4
- package/slicing/static/static-slicer.d.ts +3 -1
- package/slicing/static/static-slicer.js +6 -7
- package/statistics/features/supported/control-flow/control-flow.js +1 -1
- package/statistics/features/supported/data-access/data-access.js +1 -1
- package/statistics/features/supported/used-functions/used-functions.js +1 -1
- package/statistics/features/supported/variables/variables.js +2 -1
- package/util/containers.js +2 -2
- package/util/files.d.ts +0 -7
- package/util/files.js +0 -41
- package/util/mermaid/ast.d.ts +3 -2
- package/util/mermaid/ast.js +13 -7
- package/util/mermaid/cfg.d.ts +3 -2
- package/util/mermaid/cfg.js +26 -6
- package/util/mermaid/dfg.d.ts +2 -7
- package/util/mermaid/dfg.js +10 -6
- package/util/mermaid/info.d.ts +17 -0
- package/util/mermaid/info.js +5 -0
- package/util/prefix.d.ts +9 -5
- package/util/prefix.js +14 -6
- package/util/r-regex.d.ts +21 -0
- package/util/r-regex.js +25 -0
- package/util/simple-df/dfg-view.d.ts +2 -1
- package/util/simple-df/dfg-view.js +2 -2
- package/util/text/args.js +12 -3
- package/util/version.js +1 -1
- package/abstract-interpretation/data-frame/absint-info.d.ts +0 -109
- package/abstract-interpretation/data-frame/absint-info.js +0 -31
- package/abstract-interpretation/data-frame/absint-visitor.d.ts +0 -57
- package/abstract-interpretation/data-frame/absint-visitor.js +0 -176
- package/abstract-interpretation/data-frame/mappers/assignment-mapper.d.ts +0 -19
- package/abstract-interpretation/data-frame/mappers/assignment-mapper.js +0 -33
- package/dataflow/environments/remove.d.ts +0 -12
- package/dataflow/environments/remove.js +0 -52
- package/documentation/doc-util/doc-print.d.ts +0 -5
- package/documentation/doc-util/doc-print.js +0 -36
- package/project/plugins/file-plugins/flowr-description-file.js +0 -37
- package/project/plugins/file-plugins/notebooks/notebook.d.ts +0 -0
- package/project/plugins/file-plugins/notebooks/notebook.js +0 -2
- /package/project/plugins/file-plugins/{notebooks → files}/flowr-jupyter-file.d.ts +0 -0
- /package/project/plugins/file-plugins/{notebooks → files}/flowr-jupyter-file.js +0 -0
- /package/project/plugins/file-plugins/{notebooks → files}/flowr-rmarkdown-file.d.ts +0 -0
- /package/project/plugins/file-plugins/{notebooks → files}/flowr-rmarkdown-file.js +0 -0
|
@@ -70,7 +70,7 @@ function getConstraintType(operation) {
|
|
|
70
70
|
return DataFrameSemanticsMapper[operation].type;
|
|
71
71
|
}
|
|
72
72
|
function applyCreateSemantics(value, { colnames, rows }) {
|
|
73
|
-
const colnamesValue = colnames
|
|
73
|
+
const colnamesValue = setRange(colnames);
|
|
74
74
|
const colsValue = colnames !== undefined ? [colnames.length, colnames.length] : positive_interval_domain_1.PosIntervalTop;
|
|
75
75
|
const rowsValue = Array.isArray(rows) ? rows : typeof rows === 'number' ? [rows, rows] : positive_interval_domain_1.PosIntervalTop;
|
|
76
76
|
return new dataframe_domain_1.DataFrameDomain({
|
|
@@ -85,7 +85,7 @@ function applyReadSemantics(value, { colnames, rows }) {
|
|
|
85
85
|
function applyAccessColsSemantics(value, { columns }) {
|
|
86
86
|
if (columns?.every(col => typeof col === 'string')) {
|
|
87
87
|
return new dataframe_domain_1.DataFrameDomain({
|
|
88
|
-
colnames: value.colnames.
|
|
88
|
+
colnames: value.colnames.union(setRange(columns)),
|
|
89
89
|
cols: value.cols,
|
|
90
90
|
rows: value.rows
|
|
91
91
|
});
|
|
@@ -93,7 +93,7 @@ function applyAccessColsSemantics(value, { columns }) {
|
|
|
93
93
|
else if (columns?.every(col => typeof col === 'number')) {
|
|
94
94
|
return new dataframe_domain_1.DataFrameDomain({
|
|
95
95
|
colnames: value.colnames,
|
|
96
|
-
cols: columns
|
|
96
|
+
cols: columns.reduce((current, col) => current.max([col, col]), value.cols),
|
|
97
97
|
rows: value.rows
|
|
98
98
|
});
|
|
99
99
|
}
|
|
@@ -111,23 +111,22 @@ function applyAccessRowsSemantics(value, { rows }) {
|
|
|
111
111
|
}
|
|
112
112
|
function applyAssignColsSemantics(value, { columns }) {
|
|
113
113
|
if (columns?.every(col => typeof col === 'string')) {
|
|
114
|
-
const cols = columns.length;
|
|
115
114
|
return new dataframe_domain_1.DataFrameDomain({
|
|
116
|
-
colnames: value.colnames.
|
|
117
|
-
cols: value.cols.add([0,
|
|
115
|
+
colnames: value.colnames.union(setRange(columns)),
|
|
116
|
+
cols: value.cols.add([0, columns.length]).max([columns.length, columns.length]),
|
|
118
117
|
rows: value.rows
|
|
119
118
|
});
|
|
120
119
|
}
|
|
121
120
|
else if (columns?.every(col => typeof col === 'number')) {
|
|
122
121
|
return new dataframe_domain_1.DataFrameDomain({
|
|
123
|
-
colnames: value.colnames.
|
|
122
|
+
colnames: value.colnames.widenUp(),
|
|
124
123
|
cols: columns.reduce((current, col) => current.max([col, col]), value.cols),
|
|
125
124
|
rows: value.rows
|
|
126
125
|
});
|
|
127
126
|
}
|
|
128
127
|
return new dataframe_domain_1.DataFrameDomain({
|
|
129
|
-
colnames: value.colnames.
|
|
130
|
-
cols: value.cols.
|
|
128
|
+
colnames: value.colnames.widenUp(),
|
|
129
|
+
cols: value.cols.widenUp(),
|
|
131
130
|
rows: value.rows
|
|
132
131
|
});
|
|
133
132
|
}
|
|
@@ -142,28 +141,28 @@ function applyAssignRowsSemantics(value, { rows }) {
|
|
|
142
141
|
return new dataframe_domain_1.DataFrameDomain({
|
|
143
142
|
colnames: value.colnames,
|
|
144
143
|
cols: value.cols,
|
|
145
|
-
rows: value.rows.
|
|
144
|
+
rows: value.rows.widenUp()
|
|
146
145
|
});
|
|
147
146
|
}
|
|
148
147
|
function applySetColNamesSemantics(value, { colnames }, options) {
|
|
149
148
|
if (options?.partial) {
|
|
150
149
|
return new dataframe_domain_1.DataFrameDomain({
|
|
151
|
-
colnames:
|
|
150
|
+
colnames: value.colnames.widenDown().union(setRange(colnames)),
|
|
152
151
|
cols: value.cols,
|
|
153
152
|
rows: value.rows
|
|
154
153
|
});
|
|
155
154
|
}
|
|
156
155
|
const allColNames = colnames?.every(assert_1.isNotUndefined) && value.cols.value !== lattice_1.Bottom && colnames.length >= value.cols.value[1];
|
|
157
156
|
return new dataframe_domain_1.DataFrameDomain({
|
|
158
|
-
colnames: allColNames ? value.colnames.create(colnames) : value.colnames.
|
|
157
|
+
colnames: allColNames ? value.colnames.create(setRange(colnames)) : value.colnames.create(setRange(colnames)).widenUp(),
|
|
159
158
|
cols: value.cols,
|
|
160
159
|
rows: value.rows
|
|
161
160
|
});
|
|
162
161
|
}
|
|
163
162
|
function applyAddColsSemantics(value, { colnames }) {
|
|
164
163
|
return new dataframe_domain_1.DataFrameDomain({
|
|
165
|
-
colnames: colnames
|
|
166
|
-
cols: colnames !== undefined ? value.cols.add([colnames.length, colnames.length]) : value.cols.
|
|
164
|
+
colnames: colnames !== undefined ? value.colnames.union(setRange(colnames)) : value.colnames.widenUp(),
|
|
165
|
+
cols: colnames !== undefined ? value.cols.add([colnames.length, colnames.length]) : value.cols.widenUp(),
|
|
167
166
|
rows: value.rows
|
|
168
167
|
});
|
|
169
168
|
}
|
|
@@ -173,26 +172,26 @@ function applyAddRowsSemantics(value, { rows }) {
|
|
|
173
172
|
...value,
|
|
174
173
|
colnames: value.colnames.top(),
|
|
175
174
|
cols: rows !== undefined ? value.cols.add([1, 1]) : value.cols.top(),
|
|
176
|
-
rows: rows !== undefined ? value.rows.add([rows, rows]) : value.rows.
|
|
175
|
+
rows: rows !== undefined ? value.rows.add([rows, rows]) : value.rows.widenUp()
|
|
177
176
|
});
|
|
178
177
|
}
|
|
179
178
|
return new dataframe_domain_1.DataFrameDomain({
|
|
180
179
|
colnames: value.colnames,
|
|
181
180
|
cols: value.cols,
|
|
182
|
-
rows: rows !== undefined ? value.rows.add([rows, rows]) : value.rows.
|
|
181
|
+
rows: rows !== undefined ? value.rows.add([rows, rows]) : value.rows.widenUp()
|
|
183
182
|
});
|
|
184
183
|
}
|
|
185
184
|
function applyRemoveColsSemantics(value, { colnames }, options) {
|
|
186
185
|
if (options?.maybe) {
|
|
187
186
|
return new dataframe_domain_1.DataFrameDomain({
|
|
188
|
-
colnames: colnames !== undefined ? value.colnames.subtract(colnames
|
|
189
|
-
cols: colnames !== undefined ? value.cols.subtract([colnames.length, 0]) : value.cols.
|
|
187
|
+
colnames: colnames !== undefined ? value.colnames.subtract(setRange(colnames)) : value.colnames.widenDown(),
|
|
188
|
+
cols: colnames !== undefined ? value.cols.subtract([colnames.length, 0]) : value.cols.widenDown(),
|
|
190
189
|
rows: value.rows
|
|
191
190
|
});
|
|
192
191
|
}
|
|
193
192
|
return new dataframe_domain_1.DataFrameDomain({
|
|
194
|
-
colnames: colnames !== undefined ? value.colnames.subtract(colnames
|
|
195
|
-
cols: colnames !== undefined ? value.cols.subtract([colnames.length, colnames.length]) : value.cols.
|
|
193
|
+
colnames: colnames !== undefined ? value.colnames.subtract(setRange(colnames)) : value.colnames.widenDown(),
|
|
194
|
+
cols: colnames !== undefined ? value.cols.subtract([colnames.length, colnames.length]) : value.cols.widenDown(),
|
|
196
195
|
rows: value.rows
|
|
197
196
|
});
|
|
198
197
|
}
|
|
@@ -201,18 +200,18 @@ function applyRemoveRowsSemantics(value, { rows }, options) {
|
|
|
201
200
|
return new dataframe_domain_1.DataFrameDomain({
|
|
202
201
|
colnames: value.colnames,
|
|
203
202
|
cols: value.cols,
|
|
204
|
-
rows: rows !== undefined ? value.rows.subtract([rows, 0]) : value.rows.
|
|
203
|
+
rows: rows !== undefined ? value.rows.subtract([rows, 0]) : value.rows.widenDown()
|
|
205
204
|
});
|
|
206
205
|
}
|
|
207
206
|
return new dataframe_domain_1.DataFrameDomain({
|
|
208
207
|
colnames: value.colnames,
|
|
209
208
|
cols: value.cols,
|
|
210
|
-
rows: rows !== undefined ? value.rows.subtract([rows, rows]) : value.rows.
|
|
209
|
+
rows: rows !== undefined ? value.rows.subtract([rows, rows]) : value.rows.widenDown()
|
|
211
210
|
});
|
|
212
211
|
}
|
|
213
212
|
function applyConcatColsSemantics(value, { other }) {
|
|
214
213
|
return new dataframe_domain_1.DataFrameDomain({
|
|
215
|
-
colnames: value.colnames.
|
|
214
|
+
colnames: value.colnames.union(other.colnames),
|
|
216
215
|
cols: value.cols.add(other.cols),
|
|
217
216
|
rows: value.rows
|
|
218
217
|
});
|
|
@@ -243,13 +242,13 @@ function applySubsetColsSemantics(value, { colnames }, options) {
|
|
|
243
242
|
else if (options?.renamedCols) {
|
|
244
243
|
return new dataframe_domain_1.DataFrameDomain({
|
|
245
244
|
colnames: value.colnames.top(),
|
|
246
|
-
cols: colnames !== undefined ? value.cols.min([colnames.length, colnames.length]) : value.cols.
|
|
245
|
+
cols: colnames !== undefined ? value.cols.min([colnames.length, colnames.length]) : value.cols.widenDown(),
|
|
247
246
|
rows: value.rows
|
|
248
247
|
});
|
|
249
248
|
}
|
|
250
249
|
return new dataframe_domain_1.DataFrameDomain({
|
|
251
|
-
colnames: colnames
|
|
252
|
-
cols: colnames !== undefined ? value.cols.min([colnames.length, colnames.length]) : value.cols.
|
|
250
|
+
colnames: colnames !== undefined ? value.colnames.intersect(setRange(colnames)) : value.colnames.widenDown(),
|
|
251
|
+
cols: colnames !== undefined ? value.cols.min([colnames.length, colnames.length]) : value.cols.widenDown(),
|
|
253
252
|
rows: value.rows
|
|
254
253
|
});
|
|
255
254
|
}
|
|
@@ -264,27 +263,27 @@ function applySubsetRowsSemantics(value, { rows }, options) {
|
|
|
264
263
|
return new dataframe_domain_1.DataFrameDomain({
|
|
265
264
|
colnames: value.colnames,
|
|
266
265
|
cols: value.cols,
|
|
267
|
-
rows: rows !== undefined ? value.rows.min([rows, rows]) : value.rows.
|
|
266
|
+
rows: rows !== undefined ? value.rows.min([rows, rows]) : value.rows.widenDown()
|
|
268
267
|
});
|
|
269
268
|
}
|
|
270
269
|
function applyFilterRowsSemantics(value, { condition }) {
|
|
271
270
|
return new dataframe_domain_1.DataFrameDomain({
|
|
272
271
|
colnames: value.colnames,
|
|
273
272
|
cols: value.cols,
|
|
274
|
-
rows: condition ? value.rows : condition === false ? value.rows.create([0, 0]) : value.rows.
|
|
273
|
+
rows: condition ? value.rows : condition === false ? value.rows.create([0, 0]) : value.rows.widenDown()
|
|
275
274
|
});
|
|
276
275
|
}
|
|
277
276
|
function applyMutateColsSemantics(value, { colnames }) {
|
|
278
277
|
return new dataframe_domain_1.DataFrameDomain({
|
|
279
|
-
colnames: colnames
|
|
280
|
-
cols: colnames !== undefined ? value.cols.add([0, colnames.length]).max([colnames.length, colnames.length]) : value.cols.
|
|
278
|
+
colnames: colnames !== undefined ? value.colnames.union(setRange(colnames)) : value.colnames.widenUp(),
|
|
279
|
+
cols: colnames !== undefined ? value.cols.add([0, colnames.length]).max([colnames.length, colnames.length]) : value.cols.widenUp(),
|
|
281
280
|
rows: value.rows
|
|
282
281
|
});
|
|
283
282
|
}
|
|
284
283
|
function applyGroupBySemantics(value, { by }, options) {
|
|
285
284
|
if (options?.mutatedCols) {
|
|
286
285
|
return new dataframe_domain_1.DataFrameDomain({
|
|
287
|
-
colnames:
|
|
286
|
+
colnames: value.colnames.union(setRange(by)),
|
|
288
287
|
cols: value.cols.add([0, by.length]),
|
|
289
288
|
rows: value.rows
|
|
290
289
|
});
|
|
@@ -294,8 +293,8 @@ function applyGroupBySemantics(value, { by }, options) {
|
|
|
294
293
|
}
|
|
295
294
|
function applySummarizeSemantics(value, { colnames }) {
|
|
296
295
|
return new dataframe_domain_1.DataFrameDomain({
|
|
297
|
-
colnames: colnames
|
|
298
|
-
cols: colnames !== undefined ? value.cols.add([0, colnames.length]).min([colnames.length, +Infinity]) : value.cols.
|
|
296
|
+
colnames: colnames !== undefined ? value.colnames.join(setRange([])).union(setRange(colnames)) : value.colnames.widenUp(),
|
|
297
|
+
cols: colnames !== undefined ? value.cols.add([0, colnames.length]).min([colnames.length, +Infinity]) : value.cols.widenUp(),
|
|
299
298
|
rows: value.rows.min([1, +Infinity]).max([0, 1])
|
|
300
299
|
});
|
|
301
300
|
}
|
|
@@ -318,35 +317,36 @@ function applyJoinSemantics(value, { other, by }, options) {
|
|
|
318
317
|
return new positive_interval_domain_1.PosIntervalDomain([lower.value[0], interval1.value[1] * interval2.value[1]]);
|
|
319
318
|
}
|
|
320
319
|
};
|
|
321
|
-
|
|
322
|
-
let duplicateCols; // whether columns may be renamed due to occurrence in both data frames
|
|
320
|
+
let duplicateCols; // columns that may be renamed due to occurring in both data frames
|
|
323
321
|
let productRows; // whether the resulting rows may be a Cartesian product of the rows of the data frames
|
|
324
322
|
if (options?.natural) {
|
|
325
|
-
|
|
326
|
-
|
|
323
|
+
const commonCols = value.colnames.intersect(other.colnames).upper();
|
|
324
|
+
duplicateCols = [];
|
|
325
|
+
productRows = commonCols !== lattice_1.Bottom && commonCols !== lattice_1.Top && commonCols.size === 0;
|
|
327
326
|
}
|
|
328
327
|
else if (by === undefined) {
|
|
329
|
-
duplicateCols =
|
|
328
|
+
duplicateCols = undefined;
|
|
330
329
|
productRows = true;
|
|
331
330
|
}
|
|
332
331
|
else if (by.length === 0) {
|
|
333
|
-
|
|
332
|
+
const commonCols = value.colnames.intersect(other.colnames).upper();
|
|
333
|
+
duplicateCols = commonCols !== lattice_1.Bottom ? commonCols !== lattice_1.Top ? [...commonCols] : undefined : [];
|
|
334
334
|
productRows = true;
|
|
335
335
|
}
|
|
336
336
|
else if (by.every(assert_1.isNotUndefined)) {
|
|
337
|
-
const remainingCols =
|
|
338
|
-
duplicateCols = remainingCols.
|
|
337
|
+
const remainingCols = value.colnames.intersect(other.colnames).subtract(setRange(by)).upper();
|
|
338
|
+
duplicateCols = remainingCols !== lattice_1.Bottom ? remainingCols !== lattice_1.Top ? [...remainingCols] : undefined : [];
|
|
339
339
|
productRows = false;
|
|
340
340
|
}
|
|
341
341
|
else {
|
|
342
|
-
duplicateCols =
|
|
342
|
+
duplicateCols = undefined;
|
|
343
343
|
productRows = false;
|
|
344
344
|
}
|
|
345
345
|
const joinType = options?.join ?? 'inner';
|
|
346
346
|
let rows;
|
|
347
347
|
switch (joinType) {
|
|
348
348
|
case 'inner':
|
|
349
|
-
rows = value.rows.min(other.rows).
|
|
349
|
+
rows = value.rows.min(other.rows).widenDown();
|
|
350
350
|
break;
|
|
351
351
|
case 'left':
|
|
352
352
|
rows = value.rows;
|
|
@@ -362,7 +362,7 @@ function applyJoinSemantics(value, { other, by }, options) {
|
|
|
362
362
|
}
|
|
363
363
|
return new dataframe_domain_1.DataFrameDomain({
|
|
364
364
|
...value,
|
|
365
|
-
colnames: duplicateCols ? value.colnames.top() : value.colnames.
|
|
365
|
+
colnames: duplicateCols === undefined ? value.colnames.top() : duplicateCols.length > 0 ? value.colnames.union(other.colnames).subtract(setRange(duplicateCols)).widenUp() : value.colnames.union(other.colnames),
|
|
366
366
|
cols: by !== undefined ? value.cols.add(other.cols).subtract([by.length, by.length]) : mergeInterval(value.cols, other.cols),
|
|
367
367
|
rows: productRows ? productInterval(rows, value.rows, other.rows) : rows
|
|
368
368
|
});
|
|
@@ -377,4 +377,8 @@ function applyUnknownSemantics(value,
|
|
|
377
377
|
_args) {
|
|
378
378
|
return value.top();
|
|
379
379
|
}
|
|
380
|
+
function setRange(colnames) {
|
|
381
|
+
const names = colnames?.filter(assert_1.isNotUndefined) ?? [];
|
|
382
|
+
return { min: names, range: names.length === colnames?.length ? [] : lattice_1.Top };
|
|
383
|
+
}
|
|
380
384
|
//# sourceMappingURL=semantics.js.map
|
|
@@ -1,35 +1,59 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import type {
|
|
3
|
-
import type { RNode } from '../../r-bridge/lang-4.x/ast/model/model';
|
|
4
|
-
import type { NormalizedAst, ParentInformation } from '../../r-bridge/lang-4.x/ast/model/processing/decorate';
|
|
1
|
+
import type { DataflowGraphVertexFunctionCall } from '../../dataflow/graph/vertex';
|
|
2
|
+
import type { NoInfo } from '../../r-bridge/lang-4.x/ast/model/model';
|
|
5
3
|
import type { NodeId } from '../../r-bridge/lang-4.x/ast/model/processing/node-id';
|
|
6
|
-
import { type
|
|
7
|
-
import {
|
|
8
|
-
import type
|
|
4
|
+
import { AbstractInterpretationVisitor, type AbsintVisitorConfiguration } from '../absint-visitor';
|
|
5
|
+
import { DataFrameDomain, DataFrameStateDomain } from './dataframe-domain';
|
|
6
|
+
import { ConstraintType, type DataFrameOperationArgs, type DataFrameOperationName, type DataFrameOperationOptions } from './semantics';
|
|
7
|
+
interface Operation<Name extends DataFrameOperationName> {
|
|
8
|
+
/** The type of the abstract data frame operation (see {@link DataFrameOperationName}) */
|
|
9
|
+
operation: Name;
|
|
10
|
+
/** The ID of the data frame operand of the operation (may be `undefined`) */
|
|
11
|
+
operand: NodeId | undefined;
|
|
12
|
+
/** The optional constraint type to overwrite the default type of the operation (see {@link ConstraintType}) */
|
|
13
|
+
type?: ConstraintType;
|
|
14
|
+
/** The optional additional options for the abstract operation (see {@link DataFrameOperationOptions}) */
|
|
15
|
+
options?: DataFrameOperationOptions<Name>;
|
|
16
|
+
}
|
|
9
17
|
/**
|
|
10
|
-
*
|
|
11
|
-
* This directly attaches the inferred data frames shapes to the AST (see {@link AbstractInterpretationInfo}).
|
|
12
|
-
* @param cfinfo - The control flow information containing the control flow graph
|
|
13
|
-
* @param dfg - The data flow graph to resolve variable origins and function arguments
|
|
14
|
-
* @param ast - The abstract syntax tree to resolve node IDs to AST nodes
|
|
15
|
-
* @param ctx - The current flowr analyzer context
|
|
16
|
-
* @returns The abstract data frame state at the exit node of the control flow graph (see {@link DataFrameStateDomain}).
|
|
17
|
-
* The abstract data frame states for all other nodes are attached to the AST.
|
|
18
|
+
* An abstract data frame operation.
|
|
18
19
|
*/
|
|
19
|
-
export
|
|
20
|
+
export type DataFrameOperation<OperationName extends DataFrameOperationName = DataFrameOperationName> = {
|
|
21
|
+
[Name in OperationName]: Operation<Name> & DataFrameOperationArgs<Name>;
|
|
22
|
+
}[OperationName];
|
|
20
23
|
/**
|
|
21
|
-
*
|
|
22
|
-
* This requires that the data frame shape inference has been executed before using {@link inferDataFrameShapes}.
|
|
23
|
-
* @param id - The node or node ID to get the data frame shape for
|
|
24
|
-
* @param dfg - The data flow graph used to resolve the data frame shape
|
|
25
|
-
* @param domain - An optional abstract data frame state domain used to resolve the data frame shape (defaults to the state at the requested node)
|
|
26
|
-
* @returns The abstract data frame shape of the node, or `undefined` if no data frame shape was inferred for the node
|
|
24
|
+
* An abstract data frame operation without additional options.
|
|
27
25
|
*/
|
|
28
|
-
export
|
|
26
|
+
export type DataFrameOperationType<OperationName extends DataFrameOperationName = DataFrameOperationName> = {
|
|
27
|
+
[Name in OperationName]: Omit<Operation<Name>, 'type' | 'options'> & DataFrameOperationArgs<Name>;
|
|
28
|
+
}[OperationName];
|
|
29
29
|
/**
|
|
30
|
-
*
|
|
31
|
-
* @param node - The node to get the origins for
|
|
32
|
-
* @param dfg - The data flow graph for resolving the origins
|
|
33
|
-
* @returns The origins nodes of the variable
|
|
30
|
+
* A possible `undefined` array of abstract data frame operations (see {@link DataFrameOperation}).
|
|
34
31
|
*/
|
|
35
|
-
export
|
|
32
|
+
export type DataFrameOperations<OperationName extends DataFrameOperationName = DataFrameOperationName> = DataFrameOperation<OperationName>[] | undefined;
|
|
33
|
+
interface DataFrameShapeInferenceConfiguration extends Omit<AbsintVisitorConfiguration<DataFrameDomain>, 'domain'> {
|
|
34
|
+
readonly trackOperations?: boolean;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* The control flow graph visitor to infer the shape of data frames using abstract interpretation
|
|
38
|
+
*/
|
|
39
|
+
export declare class DataFrameShapeInferenceVisitor extends AbstractInterpretationVisitor<DataFrameDomain, NoInfo, DataFrameShapeInferenceConfiguration & {
|
|
40
|
+
domain: DataFrameStateDomain;
|
|
41
|
+
}> {
|
|
42
|
+
/**
|
|
43
|
+
* The abstract data frame operations the function call nodes are mapped to.
|
|
44
|
+
*/
|
|
45
|
+
private readonly operations?;
|
|
46
|
+
constructor({ trackOperations, ...config }: DataFrameShapeInferenceConfiguration);
|
|
47
|
+
/**
|
|
48
|
+
* Gets the mapped abstract data frame operations for an AST node (this only includes direct function calls, replacement calls, or access operations).
|
|
49
|
+
* This requires that the abstract interpretation visitor has been completed, or at least started.
|
|
50
|
+
* @param id - The ID of the node to get the mapped abstract operations for
|
|
51
|
+
* @returns The mapped abstract data frame operations for the node, or `undefined` if no abstract operation was mapped for the node or storing mapped abstract operations is disabled via the visitor config.
|
|
52
|
+
*/
|
|
53
|
+
getAbstractOperations(id: NodeId | undefined): Readonly<DataFrameOperations>;
|
|
54
|
+
protected evalFunctionCall(call: DataflowGraphVertexFunctionCall, state: DataFrameStateDomain): DataFrameStateDomain;
|
|
55
|
+
protected evalReplacementCall(call: DataflowGraphVertexFunctionCall, target: NodeId, source: NodeId, state: DataFrameStateDomain): DataFrameStateDomain;
|
|
56
|
+
protected evalAccessCall(call: DataflowGraphVertexFunctionCall, state: DataFrameStateDomain): DataFrameStateDomain;
|
|
57
|
+
private applyDataFrameExpression;
|
|
58
|
+
}
|
|
59
|
+
export {};
|
|
@@ -1,109 +1,86 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
4
|
-
|
|
5
|
-
exports.getVariableOrigins = getVariableOrigins;
|
|
6
|
-
const control_flow_graph_1 = require("../../control-flow/control-flow-graph");
|
|
7
|
-
const vertex_1 = require("../../dataflow/graph/vertex");
|
|
8
|
-
const dfg_get_origin_1 = require("../../dataflow/origin/dfg-get-origin");
|
|
9
|
-
const r_function_call_1 = require("../../r-bridge/lang-4.x/ast/model/nodes/r-function-call");
|
|
10
|
-
const type_1 = require("../../r-bridge/lang-4.x/ast/model/type");
|
|
11
|
-
const assert_1 = require("../../util/assert");
|
|
12
|
-
const abstract_domain_1 = require("../domains/abstract-domain");
|
|
13
|
-
const absint_info_1 = require("./absint-info");
|
|
14
|
-
const absint_visitor_1 = require("./absint-visitor");
|
|
3
|
+
exports.DataFrameShapeInferenceVisitor = void 0;
|
|
4
|
+
const absint_visitor_1 = require("../absint-visitor");
|
|
15
5
|
const dataframe_domain_1 = require("./dataframe-domain");
|
|
6
|
+
const access_mapper_1 = require("./mappers/access-mapper");
|
|
7
|
+
const function_mapper_1 = require("./mappers/function-mapper");
|
|
8
|
+
const replacement_mapper_1 = require("./mappers/replacement-mapper");
|
|
9
|
+
const semantics_1 = require("./semantics");
|
|
16
10
|
/**
|
|
17
|
-
*
|
|
18
|
-
* This directly attaches the inferred data frames shapes to the AST (see {@link AbstractInterpretationInfo}).
|
|
19
|
-
* @param cfinfo - The control flow information containing the control flow graph
|
|
20
|
-
* @param dfg - The data flow graph to resolve variable origins and function arguments
|
|
21
|
-
* @param ast - The abstract syntax tree to resolve node IDs to AST nodes
|
|
22
|
-
* @param ctx - The current flowr analyzer context
|
|
23
|
-
* @returns The abstract data frame state at the exit node of the control flow graph (see {@link DataFrameStateDomain}).
|
|
24
|
-
* The abstract data frame states for all other nodes are attached to the AST.
|
|
11
|
+
* The control flow graph visitor to infer the shape of data frames using abstract interpretation
|
|
25
12
|
*/
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
* This requires that the data frame shape inference has been executed before using {@link inferDataFrameShapes}.
|
|
37
|
-
* @param id - The node or node ID to get the data frame shape for
|
|
38
|
-
* @param dfg - The data flow graph used to resolve the data frame shape
|
|
39
|
-
* @param domain - An optional abstract data frame state domain used to resolve the data frame shape (defaults to the state at the requested node)
|
|
40
|
-
* @returns The abstract data frame shape of the node, or `undefined` if no data frame shape was inferred for the node
|
|
41
|
-
*/
|
|
42
|
-
function resolveIdToDataFrameShape(id, dfg, domain) {
|
|
43
|
-
const node = id === undefined || typeof id === 'object' ? id : dfg?.idMap?.get(id);
|
|
44
|
-
domain ??= node?.info.dataFrame?.domain;
|
|
45
|
-
if (dfg === undefined || node === undefined || domain === undefined) {
|
|
46
|
-
return;
|
|
13
|
+
class DataFrameShapeInferenceVisitor extends absint_visitor_1.AbstractInterpretationVisitor {
|
|
14
|
+
/**
|
|
15
|
+
* The abstract data frame operations the function call nodes are mapped to.
|
|
16
|
+
*/
|
|
17
|
+
operations;
|
|
18
|
+
constructor({ trackOperations = true, ...config }) {
|
|
19
|
+
super({ ...config, domain: dataframe_domain_1.DataFrameStateDomain.bottom() });
|
|
20
|
+
if (trackOperations) {
|
|
21
|
+
this.operations = new Map();
|
|
22
|
+
}
|
|
47
23
|
}
|
|
48
|
-
|
|
49
|
-
|
|
24
|
+
/**
|
|
25
|
+
* Gets the mapped abstract data frame operations for an AST node (this only includes direct function calls, replacement calls, or access operations).
|
|
26
|
+
* This requires that the abstract interpretation visitor has been completed, or at least started.
|
|
27
|
+
* @param id - The ID of the node to get the mapped abstract operations for
|
|
28
|
+
* @returns The mapped abstract data frame operations for the node, or `undefined` if no abstract operation was mapped for the node or storing mapped abstract operations is disabled via the visitor config.
|
|
29
|
+
*/
|
|
30
|
+
getAbstractOperations(id) {
|
|
31
|
+
return id !== undefined ? this.operations?.get(id) : undefined;
|
|
50
32
|
}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
const values = getVariableOrigins(node.info.id, dfg).map(origin => domain.get(origin.info.id));
|
|
56
|
-
if (values.length > 0 && values.every(assert_1.isNotUndefined)) {
|
|
57
|
-
return abstract_domain_1.AbstractDomain.joinAll(values);
|
|
33
|
+
evalFunctionCall(call, state) {
|
|
34
|
+
const node = this.getNormalizedAst(call.id);
|
|
35
|
+
if (node === undefined) {
|
|
36
|
+
return state;
|
|
58
37
|
}
|
|
38
|
+
const operations = (0, function_mapper_1.mapDataFrameFunctionCall)(node, this, this.config.dfg, this.config.ctx);
|
|
39
|
+
return this.applyDataFrameExpression(node, operations, state);
|
|
59
40
|
}
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
41
|
+
evalReplacementCall(call, target, source, state) {
|
|
42
|
+
const node = this.getNormalizedAst(call.id);
|
|
43
|
+
const targetNode = this.getNormalizedAst(target);
|
|
44
|
+
const sourceNode = this.getNormalizedAst(source);
|
|
45
|
+
if (node === undefined || targetNode === undefined || sourceNode === undefined) {
|
|
46
|
+
return state;
|
|
47
|
+
}
|
|
48
|
+
const operations = (0, replacement_mapper_1.mapDataFrameReplacementFunction)(node, sourceNode, this, this.config.dfg, this.config.ctx);
|
|
49
|
+
return this.applyDataFrameExpression(node, operations, state);
|
|
65
50
|
}
|
|
66
|
-
|
|
67
|
-
|
|
51
|
+
evalAccessCall(call, state) {
|
|
52
|
+
const node = this.getNormalizedAst(call.id);
|
|
53
|
+
if (node === undefined) {
|
|
54
|
+
return state;
|
|
55
|
+
}
|
|
56
|
+
const operations = (0, access_mapper_1.mapDataFrameAccess)(node, this, this.config.dfg, this.config.ctx);
|
|
57
|
+
return this.applyDataFrameExpression(node, operations, state);
|
|
68
58
|
}
|
|
69
|
-
|
|
70
|
-
if (
|
|
71
|
-
return
|
|
59
|
+
applyDataFrameExpression(node, operations, state) {
|
|
60
|
+
if (operations === undefined) {
|
|
61
|
+
return state;
|
|
72
62
|
}
|
|
73
|
-
else if (
|
|
74
|
-
|
|
63
|
+
else if (this.operations !== undefined) {
|
|
64
|
+
this.operations.set(node.info.id, operations);
|
|
75
65
|
}
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
const
|
|
80
|
-
|
|
81
|
-
|
|
66
|
+
const maxColNames = this.config.ctx.config.abstractInterpretation.dataFrame.maxColNames;
|
|
67
|
+
let value = dataframe_domain_1.DataFrameDomain.top(maxColNames);
|
|
68
|
+
for (const { operation, operand, type, options, ...args } of operations) {
|
|
69
|
+
const operandValue = operand !== undefined ? this.getAbstractValue(operand, state) : value;
|
|
70
|
+
value = (0, semantics_1.applyDataFrameSemantics)(operation, operandValue ?? dataframe_domain_1.DataFrameDomain.top(maxColNames), args, options);
|
|
71
|
+
const constraintType = type ?? (0, semantics_1.getConstraintType)(operation);
|
|
72
|
+
if (operand !== undefined && constraintType === semantics_1.ConstraintType.OperandModification) {
|
|
73
|
+
state.set(operand, value);
|
|
74
|
+
for (const origin of this.getVariableOrigins(operand)) {
|
|
75
|
+
state.set(origin, value);
|
|
76
|
+
}
|
|
82
77
|
}
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
else if (origins.includes('builtin:if-then-else') && call?.args.every(arg => arg !== r_function_call_1.EmptyArgument)) {
|
|
86
|
-
if (call.args.length === 3) {
|
|
87
|
-
const values = call.args.slice(1, 3).map(entry => resolveIdToDataFrameShape(entry.nodeId, dfg, domain));
|
|
88
|
-
if (values.length > 0 && values.every(assert_1.isNotUndefined)) {
|
|
89
|
-
return abstract_domain_1.AbstractDomain.joinAll(values);
|
|
78
|
+
else if (constraintType === semantics_1.ConstraintType.ResultPostcondition) {
|
|
79
|
+
state.set(node.info.id, value);
|
|
90
80
|
}
|
|
91
81
|
}
|
|
82
|
+
return state;
|
|
92
83
|
}
|
|
93
84
|
}
|
|
94
|
-
|
|
95
|
-
* Gets all origins of a variable in the data flow graph that have already been visited.
|
|
96
|
-
* @param node - The node to get the origins for
|
|
97
|
-
* @param dfg - The data flow graph for resolving the origins
|
|
98
|
-
* @returns The origins nodes of the variable
|
|
99
|
-
*/
|
|
100
|
-
function getVariableOrigins(node, dfg) {
|
|
101
|
-
// get each variable origin that has already been visited and whose assignment has already been processed
|
|
102
|
-
return (0, dfg_get_origin_1.getOriginInDfg)(dfg, node)
|
|
103
|
-
?.filter(origin => origin.type === 0 /* OriginType.ReadVariableOrigin */)
|
|
104
|
-
.map(entry => dfg.idMap?.get(entry.id))
|
|
105
|
-
.filter(assert_1.isNotUndefined)
|
|
106
|
-
.filter(origin => origin.info.dataFrame?.domain !== undefined)
|
|
107
|
-
.filter(origin => !(0, absint_info_1.hasDataFrameInfoMarker)(origin, absint_info_1.DataFrameInfoMarker.Unassigned)) ?? [];
|
|
108
|
-
}
|
|
85
|
+
exports.DataFrameShapeInferenceVisitor = DataFrameShapeInferenceVisitor;
|
|
109
86
|
//# sourceMappingURL=shape-inference.js.map
|
|
@@ -5,6 +5,7 @@ import { type Lattice, Top } from './lattice';
|
|
|
5
5
|
export declare const DEFAULT_INFERENCE_LIMIT = 50;
|
|
6
6
|
/**
|
|
7
7
|
* An abstract domain as complete lattice with a widening operator, narrowing operator, concretization function, and abstraction function.
|
|
8
|
+
* All operations of value abstract domains should not modify the domain in-place but return new values using {@link create}.
|
|
8
9
|
* @template Concrete - Type of an concrete element of the concrete domain for the abstract domain
|
|
9
10
|
* @template Abstract - Type of an abstract element of the abstract domain representing possible elements (excludes `Top` and `Bot`)
|
|
10
11
|
* @template Top - Type of the Top element of the abstract domain representing all possible elements
|
|
@@ -11,6 +11,7 @@ const lattice_1 = require("./lattice");
|
|
|
11
11
|
exports.DEFAULT_INFERENCE_LIMIT = 50;
|
|
12
12
|
/**
|
|
13
13
|
* An abstract domain as complete lattice with a widening operator, narrowing operator, concretization function, and abstraction function.
|
|
14
|
+
* All operations of value abstract domains should not modify the domain in-place but return new values using {@link create}.
|
|
14
15
|
* @template Concrete - Type of an concrete element of the concrete domain for the abstract domain
|
|
15
16
|
* @template Abstract - Type of an abstract element of the abstract domain representing possible elements (excludes `Top` and `Bot`)
|
|
16
17
|
* @template Top - Type of the Top element of the abstract domain representing all possible elements
|
|
@@ -73,10 +74,10 @@ function domainElementToString(value) {
|
|
|
73
74
|
return value.toString();
|
|
74
75
|
}
|
|
75
76
|
else if (value === lattice_1.Top) {
|
|
76
|
-
return
|
|
77
|
+
return lattice_1.TopSymbol;
|
|
77
78
|
}
|
|
78
79
|
else if (value === lattice_1.Bottom) {
|
|
79
|
-
return
|
|
80
|
+
return lattice_1.BottomSymbol;
|
|
80
81
|
}
|
|
81
82
|
return JSON.stringify(value);
|
|
82
83
|
}
|
|
@@ -34,10 +34,10 @@ export declare class BoundedSetDomain<T, Value extends BoundedSetLift<T> = Bound
|
|
|
34
34
|
bottom(): this & BoundedSetDomain<T, BoundedSetBottom>;
|
|
35
35
|
equals(other: this): boolean;
|
|
36
36
|
leq(other: this): boolean;
|
|
37
|
-
join(other: this): this;
|
|
38
37
|
join(other: BoundedSetLift<T> | T[]): this;
|
|
39
|
-
|
|
38
|
+
join(other: this): this;
|
|
40
39
|
meet(other: BoundedSetLift<T> | T[]): this;
|
|
40
|
+
meet(other: this): this;
|
|
41
41
|
/**
|
|
42
42
|
* Subtracts another abstract value from the current abstract value by removing all elements of the other abstract value from the current abstract value.
|
|
43
43
|
*/
|
|
@@ -125,7 +125,7 @@ class BoundedSetDomain extends abstract_domain_1.AbstractDomain {
|
|
|
125
125
|
}
|
|
126
126
|
toString() {
|
|
127
127
|
if (this.value === lattice_1.Top) {
|
|
128
|
-
return
|
|
128
|
+
return lattice_1.TopSymbol;
|
|
129
129
|
}
|
|
130
130
|
const string = this.value.values().map(abstract_domain_1.domainElementToString).toArray().join(', ');
|
|
131
131
|
return `{${string}}`;
|
|
@@ -27,10 +27,10 @@ export declare class IntervalDomain<Value extends IntervalLift = IntervalLift> e
|
|
|
27
27
|
bottom(): this & IntervalDomain<IntervalBottom>;
|
|
28
28
|
equals(other: this): boolean;
|
|
29
29
|
leq(other: this): boolean;
|
|
30
|
-
join(other: this): this;
|
|
31
30
|
join(other: IntervalLift): this;
|
|
32
|
-
|
|
31
|
+
join(other: this): this;
|
|
33
32
|
meet(other: IntervalLift): this;
|
|
33
|
+
meet(other: this): this;
|
|
34
34
|
widen(other: this): this;
|
|
35
35
|
narrow(other: this): this;
|
|
36
36
|
concretize(limit: number): ReadonlySet<number> | typeof Top;
|
|
@@ -55,11 +55,11 @@ export declare class IntervalDomain<Value extends IntervalLift = IntervalLift> e
|
|
|
55
55
|
/**
|
|
56
56
|
* Extends the lower bound of the current abstract value down to -∞.
|
|
57
57
|
*/
|
|
58
|
-
|
|
58
|
+
widenDown(): this;
|
|
59
59
|
/**
|
|
60
60
|
* Extends the upper bound of the current abstract value up to +∞.
|
|
61
61
|
*/
|
|
62
|
-
|
|
62
|
+
widenUp(): this;
|
|
63
63
|
toJson(): unknown;
|
|
64
64
|
toString(): string;
|
|
65
65
|
isTop(): this is IntervalDomain<IntervalTop>;
|