@eagleoutice/flowr 2.2.16 → 2.4.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 +48 -20
- 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 +58 -0
- package/abstract-interpretation/data-frame/absint-visitor.js +171 -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 +363 -0
- package/abstract-interpretation/data-frame/shape-inference.d.ts +38 -0
- package/abstract-interpretation/data-frame/shape-inference.js +111 -0
- package/benchmark/slicer.d.ts +15 -1
- package/benchmark/slicer.js +137 -0
- 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.js +47 -1
- package/benchmark/summarizer/second-phase/graph.js +1 -1
- package/benchmark/summarizer/second-phase/process.js +102 -4
- package/cli/benchmark-app.d.ts +2 -0
- package/cli/benchmark-app.js +2 -0
- package/cli/benchmark-helper-app.d.ts +2 -0
- package/cli/benchmark-helper-app.js +10 -3
- package/cli/common/options.js +4 -0
- package/cli/repl/commands/repl-query.js +1 -1
- package/cli/repl/server/connection.js +14 -5
- package/config.d.ts +31 -0
- package/config.js +21 -1
- package/control-flow/basic-cfg-guided-visitor.d.ts +1 -2
- package/control-flow/basic-cfg-guided-visitor.js +0 -6
- package/control-flow/cfg-simplification.d.ts +6 -0
- package/control-flow/cfg-simplification.js +18 -9
- package/control-flow/control-flow-graph.d.ts +3 -8
- package/control-flow/control-flow-graph.js +5 -6
- package/control-flow/dfg-cfg-guided-visitor.js +1 -1
- package/control-flow/extract-cfg.d.ts +2 -2
- package/control-flow/extract-cfg.js +52 -63
- package/control-flow/semantic-cfg-guided-visitor.d.ts +1 -1
- package/control-flow/semantic-cfg-guided-visitor.js +1 -1
- package/core/steps/all/static-slicing/00-slice.d.ts +7 -1
- package/core/steps/all/static-slicing/00-slice.js +9 -3
- package/core/steps/pipeline/default-pipelines.d.ts +74 -74
- package/dataflow/environments/built-in.d.ts +7 -5
- package/dataflow/environments/built-in.js +16 -13
- package/dataflow/eval/resolve/alias-tracking.js +2 -2
- package/dataflow/eval/resolve/resolve.d.ts +53 -9
- package/dataflow/eval/resolve/resolve.js +132 -38
- package/dataflow/graph/dataflowgraph-builder.js +2 -2
- package/dataflow/graph/graph.js +1 -1
- package/dataflow/graph/invert-dfg.d.ts +2 -0
- package/dataflow/graph/invert-dfg.js +17 -0
- package/dataflow/internal/process/functions/call/built-in/built-in-source.d.ts +1 -0
- package/dataflow/internal/process/functions/call/built-in/built-in-source.js +4 -0
- package/documentation/doc-util/doc-query.js +11 -1
- package/documentation/doc-util/doc-search.js +2 -2
- package/documentation/print-cfg-wiki.js +3 -4
- package/documentation/print-core-wiki.js +2 -2
- package/documentation/print-dataflow-graph-wiki.js +7 -0
- package/documentation/print-faq-wiki.js +4 -0
- package/documentation/print-interface-wiki.js +11 -0
- package/documentation/print-linter-wiki.js +36 -4
- package/documentation/print-linting-and-testing-wiki.js +13 -1
- package/documentation/print-onboarding-wiki.js +4 -0
- package/documentation/print-query-wiki.js +29 -3
- package/linter/linter-executor.js +1 -2
- package/linter/linter-format.d.ts +26 -4
- package/linter/linter-format.js +25 -6
- package/linter/linter-rules.d.ts +63 -12
- package/linter/linter-rules.js +5 -1
- package/linter/rules/absolute-path.d.ts +4 -7
- package/linter/rules/absolute-path.js +9 -6
- package/linter/rules/dataframe-access-validation.d.ts +55 -0
- package/linter/rules/dataframe-access-validation.js +118 -0
- package/linter/rules/dead-code.d.ts +43 -0
- package/linter/rules/dead-code.js +50 -0
- package/linter/rules/deprecated-functions.d.ts +3 -2
- package/linter/rules/deprecated-functions.js +3 -1
- package/linter/rules/file-path-validity.d.ts +4 -4
- package/linter/rules/file-path-validity.js +8 -6
- package/linter/rules/naming-convention.d.ts +5 -4
- package/linter/rules/naming-convention.js +8 -2
- package/linter/rules/seeded-randomness.d.ts +4 -3
- package/linter/rules/seeded-randomness.js +3 -1
- package/linter/rules/unused-definition.d.ts +2 -0
- package/linter/rules/unused-definition.js +3 -1
- package/package.json +2 -2
- package/queries/catalog/dependencies-query/dependencies-query-executor.js +6 -1
- package/queries/catalog/dependencies-query/function-info/read-functions.js +1 -0
- package/queries/catalog/dependencies-query/function-info/write-functions.js +1 -0
- 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/linter-query/linter-query-format.js +1 -1
- package/queries/catalog/location-map-query/location-map-query-executor.js +7 -5
- package/queries/catalog/location-map-query/location-map-query-format.d.ts +3 -0
- package/queries/catalog/location-map-query/location-map-query-format.js +1 -0
- package/queries/catalog/search-query/search-query-executor.js +1 -1
- package/queries/catalog/static-slice-query/static-slice-query-executor.js +2 -1
- package/queries/catalog/static-slice-query/static-slice-query-format.d.ts +3 -0
- package/queries/catalog/static-slice-query/static-slice-query-format.js +3 -1
- package/queries/query-print.d.ts +1 -1
- package/queries/query-print.js +0 -1
- package/queries/query.d.ts +77 -6
- package/queries/query.js +26 -11
- package/search/flowr-search-builder.d.ts +6 -6
- package/search/flowr-search-executor.d.ts +2 -2
- package/search/flowr-search-executor.js +1 -1
- package/search/flowr-search.d.ts +13 -8
- package/search/flowr-search.js +21 -0
- package/search/search-executor/search-enrichers.d.ts +87 -20
- package/search/search-executor/search-enrichers.js +44 -5
- package/search/search-executor/search-generators.d.ts +4 -4
- package/search/search-executor/search-generators.js +12 -7
- package/search/search-executor/search-mappers.js +3 -2
- package/search/search-executor/search-transformer.d.ts +3 -3
- package/search/search-executor/search-transformer.js +2 -2
- package/slicing/static/static-slicer.d.ts +4 -2
- package/slicing/static/static-slicer.js +10 -4
- package/util/collections/arrays.d.ts +2 -0
- package/util/collections/arrays.js +9 -0
- package/util/files.d.ts +8 -2
- package/util/files.js +22 -4
- package/util/mermaid/dfg.js +4 -2
- package/util/r-value.d.ts +23 -0
- package/util/r-value.js +113 -0
- package/util/range.d.ts +1 -0
- package/util/range.js +5 -1
- package/util/version.js +1 -1
- package/util/cfg/cfg.d.ts +0 -0
- package/util/cfg/cfg.js +0 -2
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import type { NodeId } from '../../r-bridge/lang-4.x/ast/model/processing/node-id';
|
|
2
|
+
type Interval = [number, number];
|
|
3
|
+
/** The bottom element (least element) of the positive interval domain representing no possible values, explicitly given as "bottom". */
|
|
4
|
+
export declare const IntervalBottom = "bottom";
|
|
5
|
+
/** The top element (greatest element) of the positive interval domain representing all possible values, defined as the interval from 0 to infinity. */
|
|
6
|
+
export declare const IntervalTop: [0, number];
|
|
7
|
+
/** The positive interval domain representing possible integer values. */
|
|
8
|
+
export type IntervalDomain = Interval | typeof IntervalBottom;
|
|
9
|
+
/** The bottom element (least element) of the column names domain representing no possible column name, defined as the empty list []. */
|
|
10
|
+
export declare const ColNamesBottom: [];
|
|
11
|
+
/** The top element (greatest element) of the column names domain representing all possible values, explicitly given as "top". */
|
|
12
|
+
export declare const ColNamesTop = "top";
|
|
13
|
+
/** The column names domain defined as bounded string set domain representing possible column names. */
|
|
14
|
+
export type ColNamesDomain = string[] | typeof ColNamesTop;
|
|
15
|
+
/**
|
|
16
|
+
* The data frame shape domain representing possible data frame shapes, defined as product domain of
|
|
17
|
+
* the {@link ColNamesDomain} for the columns names and {@link IntervalDomain} for the number of columns and rows.
|
|
18
|
+
* */
|
|
19
|
+
export interface DataFrameDomain {
|
|
20
|
+
colnames: ColNamesDomain;
|
|
21
|
+
cols: IntervalDomain;
|
|
22
|
+
rows: IntervalDomain;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* The bottom element (least element) of the data frame shape domain representing no possible value, mapping the columns names to {@link ColNamesBottom}
|
|
26
|
+
* and the number of columns and rows to {@link IntervalBottom}.
|
|
27
|
+
*/
|
|
28
|
+
export declare const DataFrameBottom: {
|
|
29
|
+
readonly colnames: [];
|
|
30
|
+
readonly cols: "bottom";
|
|
31
|
+
readonly rows: "bottom";
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* The top element (greatest element) of the data frame shape domain representing all possible value, mapping the columns names to {@link ColNamesTop}
|
|
35
|
+
* and the number of columns and rows to {@link IntervalTop}.
|
|
36
|
+
*/
|
|
37
|
+
export declare const DataFrameTop: {
|
|
38
|
+
readonly colnames: "top";
|
|
39
|
+
readonly cols: [0, number];
|
|
40
|
+
readonly rows: [0, number];
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* The data frame shape state domain representing possible memory states, mapping AST node IDs to data frame shape values of the {@link DataFrameDomain}.
|
|
44
|
+
*/
|
|
45
|
+
export type DataFrameStateDomain = Map<NodeId, DataFrameDomain>;
|
|
46
|
+
/** Checks if two abstract values of the column names domain are equal. */
|
|
47
|
+
export declare function equalColNames(set1: ColNamesDomain, set2: ColNamesDomain): boolean;
|
|
48
|
+
/** Checks if two abstract values of the column names domain are ordered according to the partial ordering of the column names lattice. */
|
|
49
|
+
export declare function leqColNames(set1: ColNamesDomain, set2: ColNamesDomain): boolean;
|
|
50
|
+
/** Joins two abstract values of the columns names domain according to the column names lattice by creating the least upper bound (LUB). */
|
|
51
|
+
export declare function joinColNames(set1: ColNamesDomain, set2: ColNamesDomain, maxColNames?: number): ColNamesDomain;
|
|
52
|
+
/** Meets two abstract values of the columns names domain according to the column names lattice by creating the greatest lower bound (GLB). */
|
|
53
|
+
export declare function meetColNames(set1: ColNamesDomain, set2: ColNamesDomain): ColNamesDomain;
|
|
54
|
+
/** Subtracts an abstract value from another abstract value of the column names domain by performing a set minus. */
|
|
55
|
+
export declare function subtractColNames(set1: ColNamesDomain, set2: ColNamesDomain): ColNamesDomain;
|
|
56
|
+
/**
|
|
57
|
+
* Widens two abstract values of the column names domain via naive widening to soundly over-approximate the join in (possibly infinite) fixpoint iterations.
|
|
58
|
+
*
|
|
59
|
+
* This is technically not necessary, as the join is limited by the maximum number of inferred column names.
|
|
60
|
+
* However, this speeds up the iteration in larger loops significantly, as we are over-approximating the column names much earlier.
|
|
61
|
+
*/
|
|
62
|
+
export declare function wideningColNames(set1: ColNamesDomain, set2: ColNamesDomain): ColNamesDomain;
|
|
63
|
+
/** Checks whether an abstract value of the column names domain satisfies a column name */
|
|
64
|
+
export declare function satisfiesColsNames(set: ColNamesDomain, value: string): boolean;
|
|
65
|
+
/** Checks if two abstract values of the positive interval domain are equal. */
|
|
66
|
+
export declare function equalInterval(interval1: IntervalDomain, interval2: IntervalDomain): boolean;
|
|
67
|
+
/** Checks if two abstract values of the positive interval domain are ordered according to the partial ordering of the positive interval lattice. */
|
|
68
|
+
export declare function leqInterval(interval1: IntervalDomain, interval2: IntervalDomain): boolean;
|
|
69
|
+
/** Joins two abstract values of the positive interval domain according to the positive interval lattice by creating the least upper bound (LUB). */
|
|
70
|
+
export declare function joinInterval(interval1: IntervalDomain, interval2: IntervalDomain): IntervalDomain;
|
|
71
|
+
/** Meets two abstract values of the positive interval domain according to the positive interval lattice by creating the greatest lower bound (GLB). */
|
|
72
|
+
export declare function meetInterval(interval1: IntervalDomain, interval2: IntervalDomain): IntervalDomain;
|
|
73
|
+
/** Adds two abstract values of the positive interval domain, by adding the lower bounds and upper bounds. */
|
|
74
|
+
export declare function addInterval(interval1: IntervalDomain, interval2: IntervalDomain): IntervalDomain;
|
|
75
|
+
/** Subtracts an abstract value from another abstract values of the positive interval domain, by subtracting the lower bounds and upper bounds. */
|
|
76
|
+
export declare function subtractInterval(interval1: IntervalDomain, interval2: IntervalDomain): IntervalDomain;
|
|
77
|
+
/** Creates the minium of two abstract values of the positive interval domain, by creating the minimum of the lower bounds and upper bounds. */
|
|
78
|
+
export declare function minInterval(interval1: IntervalDomain, interval2: IntervalDomain): IntervalDomain;
|
|
79
|
+
/** Creates the maximum of two abstract values of the positive interval domain, by creating the maximum of the lower bounds and upper bounds. */
|
|
80
|
+
export declare function maxInterval(interval1: IntervalDomain, interval2: IntervalDomain): IntervalDomain;
|
|
81
|
+
/** Extrends the lower bound of an abstract value of the positive interval domain to 0. */
|
|
82
|
+
export declare function extendIntervalToZero(interval: IntervalDomain): IntervalDomain;
|
|
83
|
+
/** Extrends the upper bound of an abstract value of the positive interval domain to infinity. */
|
|
84
|
+
export declare function extendIntervalToInfinity(interval: IntervalDomain): IntervalDomain;
|
|
85
|
+
/** Widens two abstract values of the positive interval domain via naive widening to soundly over-approximate the join in (possibly infinite) fixpoint iterations. */
|
|
86
|
+
export declare function wideningInterval(interval1: IntervalDomain, interval2: IntervalDomain): IntervalDomain;
|
|
87
|
+
/** Checks whether an abstract value of the positive interval domain satisfies a numeric value. */
|
|
88
|
+
export declare function satisfiesInterval(interval: IntervalDomain, value: number): boolean;
|
|
89
|
+
/** Checks whether a numeric value satisfies the less-than relation with an abstract value of the positive interval domain. */
|
|
90
|
+
export declare function satisfiesLeqInterval(interval: IntervalDomain, value: number): boolean;
|
|
91
|
+
/** Checks if two abstract values of the data frame shape domain are equal. */
|
|
92
|
+
export declare function equalDataFrameDomain(value1: DataFrameDomain, value2: DataFrameDomain): boolean;
|
|
93
|
+
/** Joins multiple abstract values of the data frame shape domain by creating the least upper bound (LUB). */
|
|
94
|
+
export declare function joinDataFrames(...values: DataFrameDomain[]): DataFrameDomain;
|
|
95
|
+
/** Meets multiple abstract values of the data frame shape domain by creating the greatest lower bound (GLB). */
|
|
96
|
+
export declare function meetDataFrames(...values: DataFrameDomain[]): DataFrameDomain;
|
|
97
|
+
/** Widens two abstract values of the data frame shape domain by widening the column names and number of columns and rows. */
|
|
98
|
+
export declare function wideningDataFrames(value1: DataFrameDomain, value2: DataFrameDomain): DataFrameDomain;
|
|
99
|
+
/** Checks if two abstract states of the data frame shape state domain are equal. */
|
|
100
|
+
export declare function equalDataFrameState(state1: DataFrameStateDomain, state2: DataFrameStateDomain): boolean;
|
|
101
|
+
/** Joins multiple abstract states of the data frame shape state domain by joining each data frame shape of the states. */
|
|
102
|
+
export declare function joinDataFrameStates(...states: DataFrameStateDomain[]): DataFrameStateDomain;
|
|
103
|
+
/** Meets multiple abstract states of the data frame shape state domain by meeting each data frame shape of the states. */
|
|
104
|
+
export declare function meetDataFrameStates(...states: DataFrameStateDomain[]): DataFrameStateDomain;
|
|
105
|
+
/** Widens two abstract states of the data frame shape state domain by widening each data frame shape of the states. */
|
|
106
|
+
export declare function wideningDataFrameStates(state1: DataFrameStateDomain, state2: DataFrameStateDomain): DataFrameStateDomain;
|
|
107
|
+
export {};
|
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DataFrameTop = exports.DataFrameBottom = exports.ColNamesTop = exports.ColNamesBottom = exports.IntervalTop = exports.IntervalBottom = void 0;
|
|
4
|
+
exports.equalColNames = equalColNames;
|
|
5
|
+
exports.leqColNames = leqColNames;
|
|
6
|
+
exports.joinColNames = joinColNames;
|
|
7
|
+
exports.meetColNames = meetColNames;
|
|
8
|
+
exports.subtractColNames = subtractColNames;
|
|
9
|
+
exports.wideningColNames = wideningColNames;
|
|
10
|
+
exports.satisfiesColsNames = satisfiesColsNames;
|
|
11
|
+
exports.equalInterval = equalInterval;
|
|
12
|
+
exports.leqInterval = leqInterval;
|
|
13
|
+
exports.joinInterval = joinInterval;
|
|
14
|
+
exports.meetInterval = meetInterval;
|
|
15
|
+
exports.addInterval = addInterval;
|
|
16
|
+
exports.subtractInterval = subtractInterval;
|
|
17
|
+
exports.minInterval = minInterval;
|
|
18
|
+
exports.maxInterval = maxInterval;
|
|
19
|
+
exports.extendIntervalToZero = extendIntervalToZero;
|
|
20
|
+
exports.extendIntervalToInfinity = extendIntervalToInfinity;
|
|
21
|
+
exports.wideningInterval = wideningInterval;
|
|
22
|
+
exports.satisfiesInterval = satisfiesInterval;
|
|
23
|
+
exports.satisfiesLeqInterval = satisfiesLeqInterval;
|
|
24
|
+
exports.equalDataFrameDomain = equalDataFrameDomain;
|
|
25
|
+
exports.joinDataFrames = joinDataFrames;
|
|
26
|
+
exports.meetDataFrames = meetDataFrames;
|
|
27
|
+
exports.wideningDataFrames = wideningDataFrames;
|
|
28
|
+
exports.equalDataFrameState = equalDataFrameState;
|
|
29
|
+
exports.joinDataFrameStates = joinDataFrameStates;
|
|
30
|
+
exports.meetDataFrameStates = meetDataFrameStates;
|
|
31
|
+
exports.wideningDataFrameStates = wideningDataFrameStates;
|
|
32
|
+
const config_1 = require("../../config");
|
|
33
|
+
const set_1 = require("../../util/collections/set");
|
|
34
|
+
const MaxColNames = config_1.defaultConfigOptions.abstractInterpretation.dataFrame.maxColNames;
|
|
35
|
+
/** The bottom element (least element) of the positive interval domain representing no possible values, explicitly given as "bottom". */
|
|
36
|
+
exports.IntervalBottom = 'bottom';
|
|
37
|
+
/** The top element (greatest element) of the positive interval domain representing all possible values, defined as the interval from 0 to infinity. */
|
|
38
|
+
exports.IntervalTop = [0, Infinity];
|
|
39
|
+
/** The bottom element (least element) of the column names domain representing no possible column name, defined as the empty list []. */
|
|
40
|
+
exports.ColNamesBottom = [];
|
|
41
|
+
/** The top element (greatest element) of the column names domain representing all possible values, explicitly given as "top". */
|
|
42
|
+
exports.ColNamesTop = 'top';
|
|
43
|
+
/**
|
|
44
|
+
* The bottom element (least element) of the data frame shape domain representing no possible value, mapping the columns names to {@link ColNamesBottom}
|
|
45
|
+
* and the number of columns and rows to {@link IntervalBottom}.
|
|
46
|
+
*/
|
|
47
|
+
exports.DataFrameBottom = {
|
|
48
|
+
colnames: exports.ColNamesBottom,
|
|
49
|
+
cols: exports.IntervalBottom,
|
|
50
|
+
rows: exports.IntervalBottom
|
|
51
|
+
};
|
|
52
|
+
/**
|
|
53
|
+
* The top element (greatest element) of the data frame shape domain representing all possible value, mapping the columns names to {@link ColNamesTop}
|
|
54
|
+
* and the number of columns and rows to {@link IntervalTop}.
|
|
55
|
+
*/
|
|
56
|
+
exports.DataFrameTop = {
|
|
57
|
+
colnames: exports.ColNamesTop,
|
|
58
|
+
cols: exports.IntervalTop,
|
|
59
|
+
rows: exports.IntervalTop
|
|
60
|
+
};
|
|
61
|
+
/** Checks if two abstract values of the column names domain are equal. */
|
|
62
|
+
function equalColNames(set1, set2) {
|
|
63
|
+
return set1 === set2 || (set1 !== exports.ColNamesTop && set2 !== exports.ColNamesTop && (0, set_1.setEquals)(new Set(set1), new Set(set2)));
|
|
64
|
+
}
|
|
65
|
+
/** Checks if two abstract values of the column names domain are ordered according to the partial ordering of the column names lattice. */
|
|
66
|
+
function leqColNames(set1, set2) {
|
|
67
|
+
return set2 === exports.ColNamesTop || (set1 !== exports.ColNamesTop && new Set(set1).isSubsetOf(new Set(set2)));
|
|
68
|
+
}
|
|
69
|
+
/** Joins two abstract values of the columns names domain according to the column names lattice by creating the least upper bound (LUB). */
|
|
70
|
+
function joinColNames(set1, set2, maxColNames = MaxColNames) {
|
|
71
|
+
if (set1 === exports.ColNamesTop || set2 === exports.ColNamesTop) {
|
|
72
|
+
return exports.ColNamesTop;
|
|
73
|
+
}
|
|
74
|
+
const join = Array.from(new Set(set1).union(new Set(set2)));
|
|
75
|
+
return join.length > maxColNames ? exports.ColNamesTop : join;
|
|
76
|
+
}
|
|
77
|
+
/** Meets two abstract values of the columns names domain according to the column names lattice by creating the greatest lower bound (GLB). */
|
|
78
|
+
function meetColNames(set1, set2) {
|
|
79
|
+
if (set1 === exports.ColNamesTop) {
|
|
80
|
+
return set2;
|
|
81
|
+
}
|
|
82
|
+
else if (set2 === exports.ColNamesTop) {
|
|
83
|
+
return set1;
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
return Array.from(new Set(set1).intersection(new Set(set2)));
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
/** Subtracts an abstract value from another abstract value of the column names domain by performing a set minus. */
|
|
90
|
+
function subtractColNames(set1, set2) {
|
|
91
|
+
if (set1 === exports.ColNamesTop) {
|
|
92
|
+
return exports.ColNamesTop;
|
|
93
|
+
}
|
|
94
|
+
else if (set2 === exports.ColNamesTop) {
|
|
95
|
+
return set1;
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
return Array.from(new Set(set1).difference(new Set(set2)));
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Widens two abstract values of the column names domain via naive widening to soundly over-approximate the join in (possibly infinite) fixpoint iterations.
|
|
103
|
+
*
|
|
104
|
+
* This is technically not necessary, as the join is limited by the maximum number of inferred column names.
|
|
105
|
+
* However, this speeds up the iteration in larger loops significantly, as we are over-approximating the column names much earlier.
|
|
106
|
+
*/
|
|
107
|
+
function wideningColNames(set1, set2) {
|
|
108
|
+
return leqColNames(set1, set2) ? set2 : exports.ColNamesTop;
|
|
109
|
+
}
|
|
110
|
+
/** Checks whether an abstract value of the column names domain satisfies a column name */
|
|
111
|
+
function satisfiesColsNames(set, value) {
|
|
112
|
+
return set === exports.ColNamesTop || set.includes(value);
|
|
113
|
+
}
|
|
114
|
+
/** Checks if two abstract values of the positive interval domain are equal. */
|
|
115
|
+
function equalInterval(interval1, interval2) {
|
|
116
|
+
return interval1 === interval2 || (interval1 !== exports.IntervalBottom && interval2 !== exports.IntervalBottom && interval1[0] === interval2[0] && interval1[1] === interval2[1]);
|
|
117
|
+
}
|
|
118
|
+
/** Checks if two abstract values of the positive interval domain are ordered according to the partial ordering of the positive interval lattice. */
|
|
119
|
+
function leqInterval(interval1, interval2) {
|
|
120
|
+
return interval1 === exports.IntervalBottom || (interval2 !== exports.IntervalBottom && interval2[0] <= interval1[0] && interval1[1] <= interval2[1]);
|
|
121
|
+
}
|
|
122
|
+
/** Joins two abstract values of the positive interval domain according to the positive interval lattice by creating the least upper bound (LUB). */
|
|
123
|
+
function joinInterval(interval1, interval2) {
|
|
124
|
+
if (interval1 === exports.IntervalBottom) {
|
|
125
|
+
return interval2;
|
|
126
|
+
}
|
|
127
|
+
else if (interval2 === exports.IntervalBottom) {
|
|
128
|
+
return interval1;
|
|
129
|
+
}
|
|
130
|
+
else {
|
|
131
|
+
return [Math.min(interval1[0], interval2[0]), Math.max(interval1[1], interval2[1])];
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
/** Meets two abstract values of the positive interval domain according to the positive interval lattice by creating the greatest lower bound (GLB). */
|
|
135
|
+
function meetInterval(interval1, interval2) {
|
|
136
|
+
if (interval1 === exports.IntervalBottom || interval2 === exports.IntervalBottom) {
|
|
137
|
+
return exports.IntervalBottom;
|
|
138
|
+
}
|
|
139
|
+
else if (Math.max(interval1[0], interval2[0]) > Math.min(interval1[1], interval2[1])) {
|
|
140
|
+
return exports.IntervalBottom;
|
|
141
|
+
}
|
|
142
|
+
else {
|
|
143
|
+
return [Math.max(interval1[0], interval2[0]), Math.min(interval1[1], interval2[1])];
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
/** Adds two abstract values of the positive interval domain, by adding the lower bounds and upper bounds. */
|
|
147
|
+
function addInterval(interval1, interval2) {
|
|
148
|
+
if (interval1 === exports.IntervalBottom || interval2 === exports.IntervalBottom) {
|
|
149
|
+
return exports.IntervalBottom;
|
|
150
|
+
}
|
|
151
|
+
else {
|
|
152
|
+
return [interval1[0] + interval2[0], interval1[1] + interval2[1]];
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
/** Subtracts an abstract value from another abstract values of the positive interval domain, by subtracting the lower bounds and upper bounds. */
|
|
156
|
+
function subtractInterval(interval1, interval2) {
|
|
157
|
+
if (interval1 === exports.IntervalBottom || interval2 === exports.IntervalBottom) {
|
|
158
|
+
return exports.IntervalBottom;
|
|
159
|
+
}
|
|
160
|
+
else {
|
|
161
|
+
return [Math.max(interval1[0] - interval2[0], 0), Math.max(interval1[1] - interval2[1], 0)];
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
/** Creates the minium of two abstract values of the positive interval domain, by creating the minimum of the lower bounds and upper bounds. */
|
|
165
|
+
function minInterval(interval1, interval2) {
|
|
166
|
+
if (interval1 === exports.IntervalBottom || interval2 === exports.IntervalBottom) {
|
|
167
|
+
return exports.IntervalBottom;
|
|
168
|
+
}
|
|
169
|
+
else {
|
|
170
|
+
return [Math.min(interval1[0], interval2[0]), Math.min(interval1[1], interval2[1])];
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
/** Creates the maximum of two abstract values of the positive interval domain, by creating the maximum of the lower bounds and upper bounds. */
|
|
174
|
+
function maxInterval(interval1, interval2) {
|
|
175
|
+
if (interval1 === exports.IntervalBottom || interval2 === exports.IntervalBottom) {
|
|
176
|
+
return exports.IntervalBottom;
|
|
177
|
+
}
|
|
178
|
+
else {
|
|
179
|
+
return [Math.max(interval1[0], interval2[0]), Math.max(interval1[1], interval2[1])];
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
/** Extrends the lower bound of an abstract value of the positive interval domain to 0. */
|
|
183
|
+
function extendIntervalToZero(interval) {
|
|
184
|
+
if (interval === exports.IntervalBottom) {
|
|
185
|
+
return exports.IntervalBottom;
|
|
186
|
+
}
|
|
187
|
+
else {
|
|
188
|
+
return [0, interval[1]];
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
/** Extrends the upper bound of an abstract value of the positive interval domain to infinity. */
|
|
192
|
+
function extendIntervalToInfinity(interval) {
|
|
193
|
+
if (interval === exports.IntervalBottom) {
|
|
194
|
+
return exports.IntervalBottom;
|
|
195
|
+
}
|
|
196
|
+
else {
|
|
197
|
+
return [interval[0], Infinity];
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
/** Widens two abstract values of the positive interval domain via naive widening to soundly over-approximate the join in (possibly infinite) fixpoint iterations. */
|
|
201
|
+
function wideningInterval(interval1, interval2) {
|
|
202
|
+
if (interval1 === exports.IntervalBottom) {
|
|
203
|
+
return interval2;
|
|
204
|
+
}
|
|
205
|
+
else if (interval2 === exports.IntervalBottom) {
|
|
206
|
+
return interval1;
|
|
207
|
+
}
|
|
208
|
+
else {
|
|
209
|
+
return [interval1[0] <= interval2[0] ? interval1[0] : 0, interval1[1] >= interval2[1] ? interval1[1] : Infinity];
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
/** Checks whether an abstract value of the positive interval domain satisfies a numeric value. */
|
|
213
|
+
function satisfiesInterval(interval, value) {
|
|
214
|
+
return interval !== exports.IntervalBottom && interval[0] <= value && value <= interval[1];
|
|
215
|
+
}
|
|
216
|
+
/** Checks whether a numeric value satisfies the less-than relation with an abstract value of the positive interval domain. */
|
|
217
|
+
function satisfiesLeqInterval(interval, value) {
|
|
218
|
+
return interval !== exports.IntervalBottom && value <= interval[1];
|
|
219
|
+
}
|
|
220
|
+
/** Checks if two abstract values of the data frame shape domain are equal. */
|
|
221
|
+
function equalDataFrameDomain(value1, value2) {
|
|
222
|
+
return value1 === value2 || (equalColNames(value1.colnames, value2.colnames) && equalInterval(value1.cols, value2.cols) && equalInterval(value1.rows, value2.rows));
|
|
223
|
+
}
|
|
224
|
+
/** Joins multiple abstract values of the data frame shape domain by creating the least upper bound (LUB). */
|
|
225
|
+
function joinDataFrames(...values) {
|
|
226
|
+
let result = values[0] ?? exports.DataFrameTop;
|
|
227
|
+
for (let i = 1; i < values.length; i++) {
|
|
228
|
+
result = {
|
|
229
|
+
colnames: joinColNames(result.colnames, values[i].colnames),
|
|
230
|
+
cols: joinInterval(result.cols, values[i].cols),
|
|
231
|
+
rows: joinInterval(result.rows, values[i].rows)
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
return result;
|
|
235
|
+
}
|
|
236
|
+
/** Meets multiple abstract values of the data frame shape domain by creating the greatest lower bound (GLB). */
|
|
237
|
+
function meetDataFrames(...values) {
|
|
238
|
+
let result = values[0] ?? exports.DataFrameTop;
|
|
239
|
+
for (let i = 1; i < values.length; i++) {
|
|
240
|
+
result = {
|
|
241
|
+
colnames: meetColNames(result.colnames, values[i].colnames),
|
|
242
|
+
cols: meetInterval(result.cols, values[i].cols),
|
|
243
|
+
rows: meetInterval(result.rows, values[i].rows)
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
return result;
|
|
247
|
+
}
|
|
248
|
+
/** Widens two abstract values of the data frame shape domain by widening the column names and number of columns and rows. */
|
|
249
|
+
function wideningDataFrames(value1, value2) {
|
|
250
|
+
return {
|
|
251
|
+
colnames: wideningColNames(value1.colnames, value2.colnames),
|
|
252
|
+
cols: wideningInterval(value1.cols, value2.cols),
|
|
253
|
+
rows: wideningInterval(value1.rows, value2.rows)
|
|
254
|
+
};
|
|
255
|
+
}
|
|
256
|
+
/** Checks if two abstract states of the data frame shape state domain are equal. */
|
|
257
|
+
function equalDataFrameState(state1, state2) {
|
|
258
|
+
if (state1 === state2) {
|
|
259
|
+
return true;
|
|
260
|
+
}
|
|
261
|
+
else if (state1.size !== state2.size) {
|
|
262
|
+
return false;
|
|
263
|
+
}
|
|
264
|
+
for (const [nodeId, value] of state1) {
|
|
265
|
+
const other = state2.get(nodeId);
|
|
266
|
+
if (other === undefined || !equalDataFrameDomain(value, other)) {
|
|
267
|
+
return false;
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
return true;
|
|
271
|
+
}
|
|
272
|
+
/** Joins multiple abstract states of the data frame shape state domain by joining each data frame shape of the states. */
|
|
273
|
+
function joinDataFrameStates(...states) {
|
|
274
|
+
const result = new Map(states[0]);
|
|
275
|
+
for (let i = 1; i < states.length; i++) {
|
|
276
|
+
for (const [nodeId, value] of states[i]) {
|
|
277
|
+
if (result.has(nodeId)) {
|
|
278
|
+
result.set(nodeId, joinDataFrames(result.get(nodeId) ?? exports.DataFrameTop, value));
|
|
279
|
+
}
|
|
280
|
+
else {
|
|
281
|
+
result.set(nodeId, value);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
return result;
|
|
286
|
+
}
|
|
287
|
+
/** Meets multiple abstract states of the data frame shape state domain by meeting each data frame shape of the states. */
|
|
288
|
+
function meetDataFrameStates(...states) {
|
|
289
|
+
const result = new Map(states[0]);
|
|
290
|
+
for (let i = 1; i < states.length; i++) {
|
|
291
|
+
for (const [nodeId, value] of states[i]) {
|
|
292
|
+
if (result.has(nodeId)) {
|
|
293
|
+
result.set(nodeId, meetDataFrames(result.get(nodeId) ?? exports.DataFrameTop, value));
|
|
294
|
+
}
|
|
295
|
+
else {
|
|
296
|
+
result.set(nodeId, value);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
return result;
|
|
301
|
+
}
|
|
302
|
+
/** Widens two abstract states of the data frame shape state domain by widening each data frame shape of the states. */
|
|
303
|
+
function wideningDataFrameStates(state1, state2) {
|
|
304
|
+
const result = new Map(state1);
|
|
305
|
+
for (const [nodeId, value] of state2) {
|
|
306
|
+
if (result.has(nodeId)) {
|
|
307
|
+
result.set(nodeId, wideningDataFrames(result.get(nodeId) ?? exports.DataFrameTop, value));
|
|
308
|
+
}
|
|
309
|
+
else {
|
|
310
|
+
result.set(nodeId, value);
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
return result;
|
|
314
|
+
}
|
|
315
|
+
//# sourceMappingURL=domain.js.map
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { DataflowGraph } from '../../../dataflow/graph/graph';
|
|
2
|
+
import type { RNode } from '../../../r-bridge/lang-4.x/ast/model/model';
|
|
3
|
+
import type { RAccess, RNamedAccess } from '../../../r-bridge/lang-4.x/ast/model/nodes/r-access';
|
|
4
|
+
import type { ParentInformation } from '../../../r-bridge/lang-4.x/ast/model/processing/decorate';
|
|
5
|
+
import type { DataFrameExpressionInfo } from '../absint-info';
|
|
6
|
+
/**
|
|
7
|
+
* Maps a concrete data frame access to abstract data frame operations.
|
|
8
|
+
*
|
|
9
|
+
* @param node - The R node of the access
|
|
10
|
+
* @param dfg - The data flow graph for resolving the arguments
|
|
11
|
+
* @returns Data frame expression info containing the mapped abstract data frame operations, or `undefined` if the node does not represent a data frame access
|
|
12
|
+
*/
|
|
13
|
+
export declare function mapDataFrameAccess(node: RNode<ParentInformation>, dfg: DataflowGraph): DataFrameExpressionInfo | undefined;
|
|
14
|
+
/**
|
|
15
|
+
* Checks whether an access node represents a string-based access (`$` or `@`), and no index-based access (`[` or `[[`).
|
|
16
|
+
*/
|
|
17
|
+
export declare function isStringBasedAccess(access: RAccess<ParentInformation>): access is RNamedAccess<ParentInformation>;
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.mapDataFrameAccess = mapDataFrameAccess;
|
|
4
|
+
exports.isStringBasedAccess = isStringBasedAccess;
|
|
5
|
+
const config_1 = require("../../../config");
|
|
6
|
+
const r_function_call_1 = require("../../../r-bridge/lang-4.x/ast/model/nodes/r-function-call");
|
|
7
|
+
const type_1 = require("../../../r-bridge/lang-4.x/ast/model/type");
|
|
8
|
+
const resolve_args_1 = require("../resolve-args");
|
|
9
|
+
const arguments_1 = require("./arguments");
|
|
10
|
+
/**
|
|
11
|
+
* Special named arguments of index-based access operators
|
|
12
|
+
*/
|
|
13
|
+
const SpecialAccessArgumentsMapper = {
|
|
14
|
+
'[': ['drop'],
|
|
15
|
+
'[[': ['exact']
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Maps a concrete data frame access to abstract data frame operations.
|
|
19
|
+
*
|
|
20
|
+
* @param node - The R node of the access
|
|
21
|
+
* @param dfg - The data flow graph for resolving the arguments
|
|
22
|
+
* @returns Data frame expression info containing the mapped abstract data frame operations, or `undefined` if the node does not represent a data frame access
|
|
23
|
+
*/
|
|
24
|
+
function mapDataFrameAccess(node, dfg) {
|
|
25
|
+
if (node.type !== type_1.RType.Access) {
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
const resolveInfo = { graph: dfg, idMap: dfg.idMap, full: true, resolve: config_1.VariableResolve.Alias };
|
|
29
|
+
let operations;
|
|
30
|
+
if (isStringBasedAccess(node)) {
|
|
31
|
+
operations = mapDataFrameNamedColumnAccess(node, resolveInfo);
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
operations = mapDataFrameIndexColRowAccess(node, resolveInfo);
|
|
35
|
+
}
|
|
36
|
+
if (operations !== undefined) {
|
|
37
|
+
return { type: 'expression', operations: operations };
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
function mapDataFrameNamedColumnAccess(access, info) {
|
|
41
|
+
const dataFrame = access.accessed;
|
|
42
|
+
if (!(0, arguments_1.isDataFrameArgument)(dataFrame, info)) {
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
const colname = (0, resolve_args_1.resolveIdToArgValueSymbolName)(access.access[0], info);
|
|
46
|
+
return [{
|
|
47
|
+
operation: 'accessCols',
|
|
48
|
+
operand: dataFrame.info.id,
|
|
49
|
+
columns: colname ? [colname] : undefined
|
|
50
|
+
}];
|
|
51
|
+
}
|
|
52
|
+
function mapDataFrameIndexColRowAccess(access, info) {
|
|
53
|
+
const dataFrame = access.accessed;
|
|
54
|
+
const drop = (0, arguments_1.getArgumentValue)(access.access, 'drop', info);
|
|
55
|
+
const exact = (0, arguments_1.getArgumentValue)(access.access, 'exact', info);
|
|
56
|
+
const args = getAccessArgs(access.operator, access.access);
|
|
57
|
+
if (!(0, arguments_1.isDataFrameArgument)(dataFrame, info)) {
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
else if (args.every(arg => arg === r_function_call_1.EmptyArgument)) {
|
|
61
|
+
return [{ operation: 'identity', operand: dataFrame.info.id }];
|
|
62
|
+
}
|
|
63
|
+
const result = [];
|
|
64
|
+
const rowArg = args.length < 2 ? undefined : args[0];
|
|
65
|
+
const colArg = args.length < 2 ? args[0] : args[1];
|
|
66
|
+
let rows = undefined;
|
|
67
|
+
let columns = undefined;
|
|
68
|
+
if (rowArg !== undefined && rowArg !== r_function_call_1.EmptyArgument) {
|
|
69
|
+
const rowValue = (0, resolve_args_1.resolveIdToArgValue)(rowArg, info);
|
|
70
|
+
if (typeof rowValue === 'number') {
|
|
71
|
+
rows = [rowValue];
|
|
72
|
+
}
|
|
73
|
+
else if (Array.isArray(rowValue) && rowValue.every(row => typeof row === 'number')) {
|
|
74
|
+
rows = rowValue;
|
|
75
|
+
}
|
|
76
|
+
result.push({
|
|
77
|
+
operation: 'accessRows',
|
|
78
|
+
operand: dataFrame.info.id,
|
|
79
|
+
rows: rows?.map(Math.abs)
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
if (colArg !== undefined && colArg !== r_function_call_1.EmptyArgument) {
|
|
83
|
+
const colValue = (0, resolve_args_1.resolveIdToArgValue)(colArg, info);
|
|
84
|
+
if (typeof colValue === 'number') {
|
|
85
|
+
columns = [colValue];
|
|
86
|
+
}
|
|
87
|
+
else if (typeof colValue === 'string' && exact !== false) {
|
|
88
|
+
columns = [colValue];
|
|
89
|
+
}
|
|
90
|
+
else if (Array.isArray(colValue) && colValue.every(col => typeof col === 'number')) {
|
|
91
|
+
columns = colValue;
|
|
92
|
+
}
|
|
93
|
+
else if (Array.isArray(colValue) && colValue.every(col => typeof col === 'string') && exact !== false) {
|
|
94
|
+
columns = colValue;
|
|
95
|
+
}
|
|
96
|
+
result.push({
|
|
97
|
+
operation: 'accessCols',
|
|
98
|
+
operand: dataFrame.info.id,
|
|
99
|
+
columns: columns?.every(col => typeof col === 'number') ? columns.map(Math.abs) : columns
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
// The data frame extent is dropped if the operator `[[` is used, the argument `drop` is true, or only one column is accessed
|
|
103
|
+
const dropExtent = access.operator === '[[' ? true :
|
|
104
|
+
args.length === 2 && typeof drop === 'boolean' ? drop :
|
|
105
|
+
rowArg !== undefined && columns?.length === 1 && (typeof columns[0] === 'string' || columns[0] > 0);
|
|
106
|
+
if (!dropExtent) {
|
|
107
|
+
const rowSubset = rows === undefined || rows.every(row => row >= 0);
|
|
108
|
+
const colSubset = columns === undefined || columns.every(col => typeof col === 'string' || col >= 0);
|
|
109
|
+
const rowZero = rows?.length === 1 && rows[0] === 0;
|
|
110
|
+
const colZero = columns?.length === 1 && columns[0] === 0;
|
|
111
|
+
const duplicateRows = rows?.some((row, index, list) => list.indexOf(row) !== index);
|
|
112
|
+
const duplicateCols = columns?.some((col, index, list) => list.indexOf(col) !== index);
|
|
113
|
+
let operand = dataFrame;
|
|
114
|
+
if (rowArg !== undefined && rowArg !== r_function_call_1.EmptyArgument) {
|
|
115
|
+
if (rowSubset) {
|
|
116
|
+
result.push({
|
|
117
|
+
operation: 'subsetRows',
|
|
118
|
+
operand: operand?.info.id,
|
|
119
|
+
rows: rowZero ? 0 : rows?.filter(index => index !== 0).length,
|
|
120
|
+
...(duplicateRows ? { options: { duplicateRows: true } } : {})
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
result.push({
|
|
125
|
+
operation: 'removeRows',
|
|
126
|
+
operand: operand?.info.id,
|
|
127
|
+
rows: rowZero ? 0 : rows?.filter(index => index !== 0).length
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
operand = undefined;
|
|
131
|
+
}
|
|
132
|
+
if (colArg !== undefined && colArg !== r_function_call_1.EmptyArgument) {
|
|
133
|
+
if (colSubset) {
|
|
134
|
+
result.push({
|
|
135
|
+
operation: 'subsetCols',
|
|
136
|
+
operand: operand?.info.id,
|
|
137
|
+
colnames: colZero ? [] : columns?.map(col => typeof col === 'string' ? col : undefined),
|
|
138
|
+
...(duplicateCols ? { options: { duplicateCols: true } } : {})
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
else {
|
|
142
|
+
result.push({
|
|
143
|
+
operation: 'removeCols',
|
|
144
|
+
operand: operand?.info.id,
|
|
145
|
+
colnames: columns?.map(col => typeof col === 'string' ? col : undefined)
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
operand = undefined;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
return result;
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Removes all special named arguments from the arguments of an access operator (i.e. arguments like "drop" and "exact").
|
|
155
|
+
*/
|
|
156
|
+
function getAccessArgs(operator, args) {
|
|
157
|
+
const specialArgs = SpecialAccessArgumentsMapper[operator];
|
|
158
|
+
return args.filter(arg => arg === r_function_call_1.EmptyArgument || arg.name === undefined || !specialArgs.includes((0, resolve_args_1.unquoteArgument)(arg.name.content)));
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Checks whether an access node represents a string-based access (`$` or `@`), and no index-based access (`[` or `[[`).
|
|
162
|
+
*/
|
|
163
|
+
function isStringBasedAccess(access) {
|
|
164
|
+
return access.operator === '$' || access.operator === '@';
|
|
165
|
+
}
|
|
166
|
+
//# sourceMappingURL=access-mapper.js.map
|