@eagleoutice/flowr 2.10.1 → 2.10.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 +27 -16
- package/abstract-interpretation/absint-visitor.d.ts +13 -8
- package/abstract-interpretation/absint-visitor.js +35 -26
- package/abstract-interpretation/data-frame/dataframe-domain.d.ts +1 -2
- package/abstract-interpretation/data-frame/dataframe-domain.js +14 -15
- package/abstract-interpretation/data-frame/mappers/access-mapper.js +2 -15
- package/abstract-interpretation/data-frame/mappers/arguments.d.ts +11 -17
- package/abstract-interpretation/data-frame/mappers/arguments.js +18 -18
- package/abstract-interpretation/data-frame/mappers/function-mapper.d.ts +41 -15
- package/abstract-interpretation/data-frame/mappers/function-mapper.js +74 -48
- package/abstract-interpretation/data-frame/mappers/replacement-mapper.js +2 -1
- package/abstract-interpretation/data-frame/semantics.d.ts +1 -1
- package/abstract-interpretation/data-frame/semantics.js +31 -35
- package/abstract-interpretation/data-frame/shape-inference.js +1 -1
- package/abstract-interpretation/domains/interval-domain.d.ts +1 -0
- package/abstract-interpretation/domains/interval-domain.js +3 -0
- package/abstract-interpretation/domains/product-domain.d.ts +9 -0
- package/abstract-interpretation/domains/product-domain.js +26 -6
- package/abstract-interpretation/domains/state-abstract-domain.d.ts +36 -22
- package/abstract-interpretation/domains/state-abstract-domain.js +169 -62
- package/abstract-interpretation/unsupported-functions.d.ts +10 -0
- package/abstract-interpretation/unsupported-functions.js +45 -0
- package/benchmark/slicer.js +10 -13
- package/cli/flowr.js +1 -1
- package/control-flow/control-flow-graph.js +13 -9
- package/control-flow/semantic-cfg-guided-visitor.d.ts +6 -0
- package/control-flow/semantic-cfg-guided-visitor.js +6 -0
- package/dataflow/environments/built-in-proc-name.d.ts +6 -0
- package/dataflow/environments/built-in-proc-name.js +6 -0
- package/dataflow/environments/built-in.d.ts +7 -5
- package/dataflow/environments/built-in.js +2 -0
- package/dataflow/environments/default-builtin-config.d.ts +442 -6
- package/dataflow/environments/default-builtin-config.js +158 -3
- package/dataflow/environments/overwrite.js +2 -5
- package/dataflow/graph/df-helper.d.ts +14 -4
- package/dataflow/graph/df-helper.js +36 -6
- package/dataflow/graph/graph.d.ts +10 -0
- package/dataflow/graph/graph.js +12 -0
- package/dataflow/instrument/instrument-dataflow-count.d.ts +10 -0
- package/dataflow/instrument/instrument-dataflow-count.js +10 -0
- package/dataflow/internal/process/functions/call/argument/unpack-argument.d.ts +4 -4
- package/dataflow/internal/process/functions/call/built-in/built-in-access.d.ts +3 -3
- package/dataflow/internal/process/functions/call/built-in/built-in-apply.d.ts +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-assignment.d.ts +3 -3
- package/dataflow/internal/process/functions/call/built-in/built-in-eval.d.ts +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-expression-list.d.ts +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-for-loop.d.ts +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-function-definition.d.ts +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-function-definition.js +6 -17
- package/dataflow/internal/process/functions/call/built-in/built-in-get.d.ts +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-if-then-else.d.ts +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-library.d.ts +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-list.d.ts +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-local.d.ts +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-pipe.d.ts +23 -3
- package/dataflow/internal/process/functions/call/built-in/built-in-pipe.js +80 -12
- package/dataflow/internal/process/functions/call/built-in/built-in-purrr-formula.d.ts +41 -0
- package/dataflow/internal/process/functions/call/built-in/built-in-purrr-formula.js +179 -0
- package/dataflow/internal/process/functions/call/built-in/built-in-quote.d.ts +7 -4
- package/dataflow/internal/process/functions/call/built-in/built-in-quote.js +62 -1
- package/dataflow/internal/process/functions/call/built-in/built-in-recall.d.ts +7 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-recall.js +15 -1
- package/dataflow/internal/process/functions/call/built-in/built-in-register-hook.d.ts +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-repeat-loop.d.ts +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-replacement.d.ts +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-rm.d.ts +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-s-seven-dispatch.d.ts +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-s-seven-new-generic.d.ts +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-s-three-dispatch.d.ts +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-source.d.ts +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-special-bin-op.d.ts +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-stop-if-not.d.ts +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-try-catch.d.ts +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-vector.d.ts +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-while-loop.d.ts +2 -2
- package/dataflow/internal/process/functions/call/common.d.ts +2 -2
- package/dataflow/internal/process/functions/call/common.js +4 -3
- package/dataflow/internal/process/functions/call/known-call-handling.d.ts +2 -2
- package/dataflow/internal/process/functions/call/named-call-handling.d.ts +2 -2
- package/documentation/wiki-absint.js +6 -5
- package/documentation/wiki-analyzer.js +0 -2
- package/documentation/wiki-linter.js +1 -0
- package/documentation/wiki-normalized-ast.js +7 -7
- package/linter/linter-rules.d.ts +24 -1
- package/linter/linter-rules.js +3 -1
- package/linter/rules/dataframe-access-validation.d.ts +1 -1
- package/linter/rules/dataframe-access-validation.js +3 -4
- package/linter/rules/roxygen-arguments.d.ts +35 -0
- package/linter/rules/roxygen-arguments.js +100 -0
- package/package.json +2 -3
- package/project/context/flowr-analyzer-context.d.ts +1 -8
- package/project/context/flowr-analyzer-context.js +1 -7
- package/project/context/flowr-analyzer-environment-context.d.ts +5 -0
- package/project/context/flowr-analyzer-environment-context.js +6 -0
- package/project/context/flowr-analyzer-files-context.d.ts +6 -0
- package/project/context/flowr-analyzer-files-context.js +4 -2
- package/project/flowr-analyzer-builder.js +1 -4
- package/queries/catalog/call-context-query/call-context-query-executor.d.ts +1 -1
- package/queries/catalog/call-context-query/call-context-query-executor.js +10 -5
- package/queries/catalog/call-context-query/call-context-query-format.d.ts +1 -1
- package/queries/catalog/dependencies-query/function-info/library-functions.js +2 -0
- package/queries/catalog/df-shape-query/df-shape-query-format.js +7 -2
- package/queries/catalog/files-query/files-query-executor.js +0 -1
- package/queries/catalog/input-sources-query/simple-input-classifier.d.ts +2 -0
- package/queries/catalog/input-sources-query/simple-input-classifier.js +2 -0
- package/r-bridge/data/data.d.ts +2 -2
- package/r-bridge/data/data.js +2 -2
- package/r-bridge/lang-4.x/ast/model/nodes/r-argument.d.ts +13 -5
- package/r-bridge/lang-4.x/ast/model/nodes/r-argument.js +14 -2
- package/r-bridge/lang-4.x/ast/model/nodes/r-function-call.d.ts +3 -3
- package/r-bridge/lang-4.x/ast/model/nodes/r-pipe.d.ts +9 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-pipe.js +13 -0
- package/r-bridge/lang-4.x/ast/model/versions.d.ts +2 -0
- package/r-bridge/lang-4.x/ast/model/versions.js +3 -1
- package/r-bridge/roxygen2/documentation-provider.js +15 -6
- package/r-bridge/roxygen2/roxygen-ast.d.ts +3 -1
- package/search/flowr-search-builder.js +3 -2
- package/util/mermaid/ast.js +2 -1
- package/util/record.d.ts +23 -0
- package/util/record.js +33 -0
- package/util/version.js +1 -1
- package/abstract-interpretation/domains/mapped-abstract-domain.d.ts +0 -41
- package/abstract-interpretation/domains/mapped-abstract-domain.js +0 -213
|
@@ -1,130 +1,231 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.MutableStateAbstractDomain = exports.StateAbstractDomain = void 0;
|
|
4
|
+
const abstract_domain_1 = require("./abstract-domain");
|
|
4
5
|
const lattice_1 = require("./lattice");
|
|
5
|
-
const mapped_abstract_domain_1 = require("./mapped-abstract-domain");
|
|
6
6
|
/**
|
|
7
|
-
* A state abstract domain
|
|
8
|
-
* The Bottom element is defined as
|
|
9
|
-
* @template Domain - Type of the abstract domain to map the AST node IDs to
|
|
7
|
+
* A state abstract domain that maps AST node IDs of a program to abstract values of an abstract domain.
|
|
8
|
+
* The Bottom element is defined as {@link Bottom} symbol and the Top element as empty mapping.
|
|
9
|
+
* @template Domain - Type of the value abstract domain to map the AST node IDs to
|
|
10
10
|
* @see {@link NodeId} for the node IDs of the AST nodes
|
|
11
11
|
*/
|
|
12
|
-
class StateAbstractDomain extends
|
|
13
|
-
|
|
14
|
-
constructor(value,
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
this._isBottom = true;
|
|
12
|
+
class StateAbstractDomain extends abstract_domain_1.AbstractDomain {
|
|
13
|
+
domain;
|
|
14
|
+
constructor(value, domain) {
|
|
15
|
+
if (value === lattice_1.Bottom || value.values().some(entry => entry.isBottom())) {
|
|
16
|
+
super(lattice_1.Bottom);
|
|
18
17
|
}
|
|
18
|
+
else {
|
|
19
|
+
super(new Map(value));
|
|
20
|
+
}
|
|
21
|
+
this.domain = domain;
|
|
22
|
+
}
|
|
23
|
+
create(value) {
|
|
24
|
+
return new StateAbstractDomain(value, this.domain);
|
|
25
|
+
}
|
|
26
|
+
static top(domain) {
|
|
27
|
+
return new StateAbstractDomain(new Map(), domain);
|
|
19
28
|
}
|
|
20
|
-
|
|
21
|
-
return new StateAbstractDomain(
|
|
29
|
+
static bottom(domain) {
|
|
30
|
+
return new StateAbstractDomain(lattice_1.Bottom, domain);
|
|
22
31
|
}
|
|
23
|
-
|
|
24
|
-
return
|
|
32
|
+
get(key) {
|
|
33
|
+
return this.value === lattice_1.Bottom ? this.domain.bottom() : this.value.get(key);
|
|
25
34
|
}
|
|
26
|
-
|
|
27
|
-
return this.
|
|
35
|
+
has(key) {
|
|
36
|
+
return this.value !== lattice_1.Bottom && this.value.has(key);
|
|
28
37
|
}
|
|
29
38
|
set(key, value) {
|
|
30
|
-
if (value.
|
|
31
|
-
this.
|
|
39
|
+
if (this.value === lattice_1.Bottom) {
|
|
40
|
+
this._value = new Map();
|
|
32
41
|
}
|
|
33
|
-
|
|
42
|
+
this._value.set(key, value);
|
|
34
43
|
}
|
|
35
|
-
|
|
36
|
-
|
|
44
|
+
remove(key) {
|
|
45
|
+
if (this.value !== lattice_1.Bottom) {
|
|
46
|
+
this._value.delete(key);
|
|
47
|
+
}
|
|
37
48
|
}
|
|
38
49
|
top() {
|
|
39
|
-
return this.
|
|
50
|
+
return StateAbstractDomain.top(this.domain);
|
|
51
|
+
}
|
|
52
|
+
bottom() {
|
|
53
|
+
return StateAbstractDomain.bottom(this.domain);
|
|
40
54
|
}
|
|
41
55
|
equals(other) {
|
|
42
|
-
if (this.
|
|
56
|
+
if (this.value === other.value) {
|
|
57
|
+
return true;
|
|
58
|
+
}
|
|
59
|
+
else if (this.value === lattice_1.Bottom || other.value === lattice_1.Bottom || this.value.size !== other.value.size) {
|
|
43
60
|
return false;
|
|
44
61
|
}
|
|
45
|
-
|
|
62
|
+
for (const [key, value] of this.value.entries()) {
|
|
63
|
+
const otherValue = other.get(key);
|
|
64
|
+
if (otherValue === undefined || !value.equals(otherValue)) {
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return true;
|
|
46
69
|
}
|
|
47
70
|
leq(other) {
|
|
48
|
-
if (this.
|
|
71
|
+
if (this.value === other.value || this.value === lattice_1.Bottom) {
|
|
49
72
|
return true;
|
|
50
73
|
}
|
|
51
|
-
else if (other.
|
|
74
|
+
else if (other.value === lattice_1.Bottom || this.value.size > other.value.size) {
|
|
52
75
|
return false;
|
|
53
76
|
}
|
|
54
|
-
|
|
77
|
+
for (const [key, value] of this.value.entries()) {
|
|
78
|
+
const otherValue = other.get(key);
|
|
79
|
+
if (otherValue === undefined || !value.leq(otherValue)) {
|
|
80
|
+
return false;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
return true;
|
|
55
84
|
}
|
|
56
85
|
join(other) {
|
|
57
|
-
if (this.
|
|
58
|
-
return
|
|
86
|
+
if (this.value === lattice_1.Bottom) {
|
|
87
|
+
return this.create(other.value);
|
|
59
88
|
}
|
|
60
|
-
else if (other.
|
|
89
|
+
else if (other.value === lattice_1.Bottom) {
|
|
61
90
|
return this.create(this.value);
|
|
62
91
|
}
|
|
63
|
-
|
|
92
|
+
const result = this.create(this.value);
|
|
93
|
+
for (const [key, value] of other.value.entries()) {
|
|
94
|
+
const currValue = result.get(key);
|
|
95
|
+
if (currValue === undefined) {
|
|
96
|
+
result.set(key, value);
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
result.set(key, currValue.join(value));
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
return result;
|
|
64
103
|
}
|
|
65
104
|
meet(other) {
|
|
66
|
-
|
|
67
|
-
|
|
105
|
+
if (this.value === lattice_1.Bottom || other.value === lattice_1.Bottom) {
|
|
106
|
+
return this.bottom();
|
|
107
|
+
}
|
|
108
|
+
const result = this.create(this.value);
|
|
109
|
+
for (const key of result.value.keys()) {
|
|
110
|
+
if (!other.has(key)) {
|
|
111
|
+
result.remove(key);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
for (const [key, value] of other.value.entries()) {
|
|
115
|
+
const currValue = result.get(key);
|
|
116
|
+
if (currValue !== undefined) {
|
|
117
|
+
result.set(key, currValue.meet(value));
|
|
118
|
+
}
|
|
119
|
+
}
|
|
68
120
|
return result;
|
|
69
121
|
}
|
|
70
122
|
widen(other) {
|
|
71
|
-
if (this.
|
|
72
|
-
return
|
|
123
|
+
if (this.value === lattice_1.Bottom) {
|
|
124
|
+
return this.create(other.value);
|
|
73
125
|
}
|
|
74
|
-
else if (other.
|
|
126
|
+
else if (other.value === lattice_1.Bottom) {
|
|
75
127
|
return this.create(this.value);
|
|
76
128
|
}
|
|
77
|
-
|
|
129
|
+
const result = this.create(this.value);
|
|
130
|
+
for (const [key, value] of other.value.entries()) {
|
|
131
|
+
const currValue = result.get(key);
|
|
132
|
+
if (currValue === undefined) {
|
|
133
|
+
result.set(key, value);
|
|
134
|
+
}
|
|
135
|
+
else {
|
|
136
|
+
result.set(key, currValue.widen(value));
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
return result;
|
|
78
140
|
}
|
|
79
141
|
narrow(other) {
|
|
80
|
-
|
|
81
|
-
|
|
142
|
+
if (this.value === lattice_1.Bottom || other.value === lattice_1.Bottom) {
|
|
143
|
+
return this.bottom();
|
|
144
|
+
}
|
|
145
|
+
const result = this.create(this.value);
|
|
146
|
+
for (const key of result.value.keys()) {
|
|
147
|
+
if (!other.has(key)) {
|
|
148
|
+
result.remove(key);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
for (const [key, value] of other.value.entries()) {
|
|
152
|
+
const currValue = result.get(key);
|
|
153
|
+
if (currValue !== undefined) {
|
|
154
|
+
result.set(key, currValue.narrow(value));
|
|
155
|
+
}
|
|
156
|
+
}
|
|
82
157
|
return result;
|
|
83
158
|
}
|
|
84
159
|
concretize(limit) {
|
|
85
|
-
if (this.
|
|
160
|
+
if (this.value === lattice_1.Bottom) {
|
|
86
161
|
return new Set();
|
|
87
162
|
}
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
163
|
+
let mappings = new Set([new Map()]);
|
|
164
|
+
for (const [key, value] of this.value.entries()) {
|
|
165
|
+
const concreteValues = value.concretize(limit);
|
|
166
|
+
if (concreteValues === lattice_1.Top) {
|
|
167
|
+
return lattice_1.Top;
|
|
168
|
+
}
|
|
169
|
+
const newMappings = new Set();
|
|
170
|
+
for (const state of mappings) {
|
|
171
|
+
for (const concrete of concreteValues) {
|
|
172
|
+
if (newMappings.size > limit) {
|
|
173
|
+
return lattice_1.Top;
|
|
174
|
+
}
|
|
175
|
+
const map = new Map(state);
|
|
176
|
+
map.set(key, concrete);
|
|
177
|
+
newMappings.add(map);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
mappings = newMappings;
|
|
181
|
+
}
|
|
182
|
+
return mappings;
|
|
92
183
|
}
|
|
93
184
|
abstract(concrete) {
|
|
94
185
|
if (concrete === lattice_1.Top) {
|
|
95
186
|
return this.top();
|
|
96
187
|
}
|
|
97
188
|
else if (concrete.size === 0) {
|
|
98
|
-
return this.
|
|
99
|
-
}
|
|
100
|
-
|
|
189
|
+
return this.bottom();
|
|
190
|
+
}
|
|
191
|
+
const mapping = new Map();
|
|
192
|
+
for (const concreteMapping of concrete) {
|
|
193
|
+
for (const [key, value] of concreteMapping) {
|
|
194
|
+
const set = mapping.get(key);
|
|
195
|
+
if (set === undefined) {
|
|
196
|
+
mapping.set(key, new Set([value]));
|
|
197
|
+
}
|
|
198
|
+
else {
|
|
199
|
+
set.add(value);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
const result = new Map();
|
|
204
|
+
for (const [key, values] of mapping) {
|
|
205
|
+
result.set(key, this.domain.abstract(values));
|
|
206
|
+
}
|
|
207
|
+
return this.create(result);
|
|
101
208
|
}
|
|
102
209
|
toJson() {
|
|
103
|
-
if (this.
|
|
104
|
-
return
|
|
105
|
-
}
|
|
106
|
-
else if (this.value.size === 0) {
|
|
107
|
-
return lattice_1.TopSymbol;
|
|
210
|
+
if (this.value === lattice_1.Bottom) {
|
|
211
|
+
return this.value.description;
|
|
108
212
|
}
|
|
109
|
-
return
|
|
213
|
+
return Object.fromEntries(this.value.entries().map(([key, value]) => [key, value.toJson()]));
|
|
110
214
|
}
|
|
111
215
|
toString() {
|
|
112
|
-
if (this.
|
|
216
|
+
if (this.value === lattice_1.Bottom) {
|
|
113
217
|
return lattice_1.BottomSymbol;
|
|
114
218
|
}
|
|
115
|
-
|
|
116
|
-
return lattice_1.TopSymbol;
|
|
117
|
-
}
|
|
118
|
-
return super.toString();
|
|
219
|
+
return '(' + this.value.entries().toArray().map(([key, value]) => `${(0, abstract_domain_1.domainElementToString)(key)} -> ${value.toString()}`).join(', ') + ')';
|
|
119
220
|
}
|
|
120
221
|
isTop() {
|
|
121
|
-
return this.value.size === 0;
|
|
222
|
+
return this.value !== lattice_1.Bottom && this.value.size === 0;
|
|
122
223
|
}
|
|
123
224
|
isBottom() {
|
|
124
|
-
return this.
|
|
225
|
+
return this.value == lattice_1.Bottom;
|
|
125
226
|
}
|
|
126
227
|
isValue() {
|
|
127
|
-
return
|
|
228
|
+
return this.value !== lattice_1.Bottom;
|
|
128
229
|
}
|
|
129
230
|
}
|
|
130
231
|
exports.StateAbstractDomain = StateAbstractDomain;
|
|
@@ -133,7 +234,13 @@ exports.StateAbstractDomain = StateAbstractDomain;
|
|
|
133
234
|
*/
|
|
134
235
|
class MutableStateAbstractDomain extends StateAbstractDomain {
|
|
135
236
|
create(value) {
|
|
136
|
-
return new MutableStateAbstractDomain(value);
|
|
237
|
+
return new MutableStateAbstractDomain(value, this.domain);
|
|
238
|
+
}
|
|
239
|
+
static top(domain) {
|
|
240
|
+
return new MutableStateAbstractDomain(new Map(), domain);
|
|
241
|
+
}
|
|
242
|
+
static bottom(domain) {
|
|
243
|
+
return new MutableStateAbstractDomain(lattice_1.Bottom, domain);
|
|
137
244
|
}
|
|
138
245
|
set(key, value) {
|
|
139
246
|
super.set(key, value);
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type DataflowGraphVertexArgument } from '../dataflow/graph/vertex';
|
|
2
|
+
/**
|
|
3
|
+
* Helper for unsupported functions that may change the environment.
|
|
4
|
+
*/
|
|
5
|
+
export declare const UnsupportedFunctions: {
|
|
6
|
+
/**
|
|
7
|
+
* Checks whether a data flow graph vertex represents a unsupported (environment-changing) function call (e.g. `eval`, `load`, `attach`, `rm`, ...)
|
|
8
|
+
*/
|
|
9
|
+
isUnsupportedCall(this: void, vertex: DataflowGraphVertexArgument | undefined): boolean;
|
|
10
|
+
};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.UnsupportedFunctions = void 0;
|
|
4
|
+
const identifier_1 = require("../dataflow/environments/identifier");
|
|
5
|
+
const vertex_1 = require("../dataflow/graph/vertex");
|
|
6
|
+
/**
|
|
7
|
+
* List of known function calls that may change the environment unresolvable/implicitly.
|
|
8
|
+
*/
|
|
9
|
+
const UnsupportedFunctionsList = {
|
|
10
|
+
'.Primitive': { package: 'base' },
|
|
11
|
+
'.Internal': { package: 'base' },
|
|
12
|
+
'.External': { package: 'base' },
|
|
13
|
+
'.Call': { package: 'base' },
|
|
14
|
+
'.C': { package: 'base' },
|
|
15
|
+
'.Fortran': { package: 'base' },
|
|
16
|
+
'.dyn.load': { package: 'base' },
|
|
17
|
+
'eval': { package: 'base' },
|
|
18
|
+
'evalq': { package: 'base' },
|
|
19
|
+
'eval.parent': { package: 'base' },
|
|
20
|
+
'eval_tidy': { package: 'rlang' },
|
|
21
|
+
'eval_bare': { package: 'rlang' },
|
|
22
|
+
'body<-': { package: 'base' },
|
|
23
|
+
'formals<-': { package: 'base' },
|
|
24
|
+
'environment<-': { package: 'base' },
|
|
25
|
+
'load': { package: 'base' },
|
|
26
|
+
'attach': { package: 'base' },
|
|
27
|
+
'detach': { package: 'base' },
|
|
28
|
+
'rm': { package: 'base' },
|
|
29
|
+
'remove': { package: 'base' },
|
|
30
|
+
'list2env': { package: 'base' },
|
|
31
|
+
'assignInNamespace': { package: 'utils' },
|
|
32
|
+
'assignInMyNamespace': { package: 'utils' },
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* Helper for unsupported functions that may change the environment.
|
|
36
|
+
*/
|
|
37
|
+
exports.UnsupportedFunctions = {
|
|
38
|
+
/**
|
|
39
|
+
* Checks whether a data flow graph vertex represents a unsupported (environment-changing) function call (e.g. `eval`, `load`, `attach`, `rm`, ...)
|
|
40
|
+
*/
|
|
41
|
+
isUnsupportedCall(vertex) {
|
|
42
|
+
return (0, vertex_1.isFunctionCallVertex)(vertex) && Object.hasOwn(UnsupportedFunctionsList, identifier_1.Identifier.getName(vertex.name));
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
//# sourceMappingURL=unsupported-functions.js.map
|
package/benchmark/slicer.js
CHANGED
|
@@ -26,7 +26,6 @@ const arrays_1 = require("../util/collections/arrays");
|
|
|
26
26
|
const config_1 = require("../config");
|
|
27
27
|
const extract_cfg_1 = require("../control-flow/extract-cfg");
|
|
28
28
|
const shape_inference_1 = require("../abstract-interpretation/data-frame/shape-inference");
|
|
29
|
-
const lattice_1 = require("../abstract-interpretation/domains/lattice");
|
|
30
29
|
const set_range_domain_1 = require("../abstract-interpretation/domains/set-range-domain");
|
|
31
30
|
const fs_1 = __importDefault(require("fs"));
|
|
32
31
|
const flowr_analyzer_context_1 = require("../project/context/flowr-analyzer-context");
|
|
@@ -269,9 +268,9 @@ class BenchmarkSlicer {
|
|
|
269
268
|
const inference = new shape_inference_1.DataFrameShapeInferenceVisitor({ controlFlow: cfinfo, dfg, normalizedAst: ast, ctx: this.context });
|
|
270
269
|
this.measureSimpleStep('infer data frame shapes', () => inference.start());
|
|
271
270
|
const result = inference.getEndState();
|
|
272
|
-
stats.numberOfResultConstraints = result.value.size;
|
|
273
|
-
stats.sizeOfInfo = (0, size_of_1.safeSizeOf)(
|
|
274
|
-
for (const value of result.value.values()) {
|
|
271
|
+
stats.numberOfResultConstraints = result.isValue() ? result.value.size : 0;
|
|
272
|
+
stats.sizeOfInfo = (0, size_of_1.safeSizeOf)(inference.getAbstractTrace().entries().toArray());
|
|
273
|
+
for (const value of result.isValue() ? result.value.values() : []) {
|
|
275
274
|
if (value.isTop()) {
|
|
276
275
|
stats.numberOfResultingTop++;
|
|
277
276
|
}
|
|
@@ -290,8 +289,9 @@ class BenchmarkSlicer {
|
|
|
290
289
|
stats.numberOfEmptyNodes++;
|
|
291
290
|
return;
|
|
292
291
|
}
|
|
292
|
+
const state = inference.getAbstractState(node.info.id);
|
|
293
293
|
const nodeStats = {
|
|
294
|
-
numberOfEntries:
|
|
294
|
+
numberOfEntries: state?.isValue() ? state.value.size : 0
|
|
295
295
|
};
|
|
296
296
|
if (operations !== undefined) {
|
|
297
297
|
nodeStats.mappedOperations = operations.map(op => op.operation);
|
|
@@ -322,7 +322,7 @@ class BenchmarkSlicer {
|
|
|
322
322
|
getInferredRange(value) {
|
|
323
323
|
if (value.isValue()) {
|
|
324
324
|
if (value instanceof set_range_domain_1.SetRangeDomain) {
|
|
325
|
-
return value.
|
|
325
|
+
return value.isFinite() ? value.value.range.size : Infinity;
|
|
326
326
|
}
|
|
327
327
|
else {
|
|
328
328
|
return value.value[1] - value.value[0];
|
|
@@ -335,16 +335,13 @@ class BenchmarkSlicer {
|
|
|
335
335
|
return 'top';
|
|
336
336
|
}
|
|
337
337
|
else if (value.isValue()) {
|
|
338
|
-
if (value
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
338
|
+
if (!value.isFinite()) {
|
|
339
|
+
return 'infinite';
|
|
340
|
+
}
|
|
341
|
+
else if (value instanceof set_range_domain_1.SetRangeDomain) {
|
|
342
342
|
return Math.floor(value.value.min.size + (value.value.range.size / 2));
|
|
343
343
|
}
|
|
344
344
|
else {
|
|
345
|
-
if (!isFinite(value.value[1])) {
|
|
346
|
-
return 'infinite';
|
|
347
|
-
}
|
|
348
345
|
return Math.floor((value.value[0] + value.value[1]) / 2);
|
|
349
346
|
}
|
|
350
347
|
}
|
package/cli/flowr.js
CHANGED
|
@@ -140,7 +140,7 @@ async function mainRepl() {
|
|
|
140
140
|
await (0, print_version_1.printVersionRepl)(defaultEngine);
|
|
141
141
|
const w = (x) => ansi_1.ansiFormatter.format(x, { color: 7 /* Colors.White */, effect: ansi_1.ColorEffect.Foreground, style: 3 /* FontStyles.Italic */ });
|
|
142
142
|
console.log(w('use ') + ansi_1.ansiFormatter.format(':help', { color: 7 /* Colors.White */, effect: ansi_1.ColorEffect.Foreground, style: 1 /* FontStyles.Bold */ }) + w(' to get a list of available commands.'));
|
|
143
|
-
await (0, core_1.repl)({ analyzer
|
|
143
|
+
await (0, core_1.repl)({ analyzer, allowRSessionAccess });
|
|
144
144
|
}
|
|
145
145
|
process.exit(0);
|
|
146
146
|
}
|
|
@@ -589,16 +589,20 @@ class ControlFlowGraph {
|
|
|
589
589
|
* @see {@link ControlFlowGraph#addEdges|addEdges()} - to add multiple edges at once
|
|
590
590
|
*/
|
|
591
591
|
addEdge(from, to, edge) {
|
|
592
|
-
const edgesFrom = this.edgeInfos.get(from)
|
|
593
|
-
if (!
|
|
594
|
-
this.edgeInfos.set(from,
|
|
592
|
+
const edgesFrom = this.edgeInfos.get(from);
|
|
593
|
+
if (!edgesFrom) {
|
|
594
|
+
this.edgeInfos.set(from, new Map([[to, edge]]));
|
|
595
|
+
}
|
|
596
|
+
else {
|
|
597
|
+
edgesFrom.set(to, edge);
|
|
595
598
|
}
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
599
|
+
const edgesTo = this.revEdgeInfos.get(to);
|
|
600
|
+
if (!edgesTo) {
|
|
601
|
+
this.revEdgeInfos.set(to, new Map([[from, edge]]));
|
|
602
|
+
}
|
|
603
|
+
else {
|
|
604
|
+
edgesTo.set(from, edge);
|
|
600
605
|
}
|
|
601
|
-
edgesTo.set(from, edge);
|
|
602
606
|
return this;
|
|
603
607
|
}
|
|
604
608
|
/**
|
|
@@ -762,7 +766,7 @@ class ControlFlowGraph {
|
|
|
762
766
|
const roots = other.roots;
|
|
763
767
|
if (this._mayBB) {
|
|
764
768
|
for (const [id, node] of other.vtxInfos) {
|
|
765
|
-
this.addVertex(node, forceNested
|
|
769
|
+
this.addVertex(node, !forceNested && roots.has(id));
|
|
766
770
|
}
|
|
767
771
|
}
|
|
768
772
|
else {
|
|
@@ -566,4 +566,10 @@ export declare class SemanticCfgGuidedVisitor<OtherInfo = NoInfo, ControlFlow ex
|
|
|
566
566
|
protected onRecallCall(_data: {
|
|
567
567
|
call: DataflowGraphVertexFunctionCall;
|
|
568
568
|
}): void;
|
|
569
|
+
/**
|
|
570
|
+
* This event triggers for any purr formula as in `map(df, ~ .x + 1)`
|
|
571
|
+
*/
|
|
572
|
+
protected onPurrFormulaCall(_data: {
|
|
573
|
+
call: DataflowGraphVertexFunctionCall;
|
|
574
|
+
}): void;
|
|
569
575
|
}
|
|
@@ -278,6 +278,8 @@ class SemanticCfgGuidedVisitor extends dfg_cfg_guided_visitor_1.DataflowAwareCfg
|
|
|
278
278
|
return this.onUnnamedCall({ call });
|
|
279
279
|
case built_in_proc_name_1.BuiltInProcName.Recall:
|
|
280
280
|
return this.onRecallCall({ call });
|
|
281
|
+
case built_in_proc_name_1.BuiltInProcName.PurrrFormula:
|
|
282
|
+
return this.onPurrFormulaCall({ call });
|
|
281
283
|
case built_in_proc_name_1.BuiltInProcName.Default:
|
|
282
284
|
case built_in_proc_name_1.BuiltInProcName.DefaultReadAllArgs:
|
|
283
285
|
case built_in_proc_name_1.BuiltInProcName.Function:
|
|
@@ -640,6 +642,10 @@ class SemanticCfgGuidedVisitor extends dfg_cfg_guided_visitor_1.DataflowAwareCfg
|
|
|
640
642
|
* @protected
|
|
641
643
|
*/
|
|
642
644
|
onRecallCall(_data) { }
|
|
645
|
+
/**
|
|
646
|
+
* This event triggers for any purr formula as in `map(df, ~ .x + 1)`
|
|
647
|
+
*/
|
|
648
|
+
onPurrFormulaCall(_data) { }
|
|
643
649
|
}
|
|
644
650
|
exports.SemanticCfgGuidedVisitor = SemanticCfgGuidedVisitor;
|
|
645
651
|
//# sourceMappingURL=semantic-cfg-guided-visitor.js.map
|
|
@@ -38,6 +38,12 @@ export declare enum BuiltInProcName {
|
|
|
38
38
|
Local = "builtin:local",
|
|
39
39
|
/** for the pipe operators, see {@link processPipe} */
|
|
40
40
|
Pipe = "builtin:pipe",
|
|
41
|
+
/**
|
|
42
|
+
* Support for purrr's functional style of formulas with implicit arguments,
|
|
43
|
+
* for example, supports `map(g, ~ .x + 2)`
|
|
44
|
+
* @see {@link processPurrrFormula}
|
|
45
|
+
*/
|
|
46
|
+
PurrrFormula = "builtin:purrr-formula",
|
|
41
47
|
/** for `quote`, and other substituting calls, see {@link processQuote} */
|
|
42
48
|
Quote = "builtin:quote",
|
|
43
49
|
/**
|
|
@@ -42,6 +42,12 @@ var BuiltInProcName;
|
|
|
42
42
|
BuiltInProcName["Local"] = "builtin:local";
|
|
43
43
|
/** for the pipe operators, see {@link processPipe} */
|
|
44
44
|
BuiltInProcName["Pipe"] = "builtin:pipe";
|
|
45
|
+
/**
|
|
46
|
+
* Support for purrr's functional style of formulas with implicit arguments,
|
|
47
|
+
* for example, supports `map(g, ~ .x + 2)`
|
|
48
|
+
* @see {@link processPurrrFormula}
|
|
49
|
+
*/
|
|
50
|
+
BuiltInProcName["PurrrFormula"] = "builtin:purrr-formula";
|
|
45
51
|
/** for `quote`, and other substituting calls, see {@link processQuote} */
|
|
46
52
|
BuiltInProcName["Quote"] = "builtin:quote";
|
|
47
53
|
/**
|
|
@@ -15,7 +15,7 @@ import { processFunctionDefinition } from '../internal/process/functions/call/bu
|
|
|
15
15
|
import { processExpressionList } from '../internal/process/functions/call/built-in/built-in-expression-list';
|
|
16
16
|
import { processGet } from '../internal/process/functions/call/built-in/built-in-get';
|
|
17
17
|
import type { AstIdMap, ParentInformation, RNodeWithParent } from '../../r-bridge/lang-4.x/ast/model/processing/decorate';
|
|
18
|
-
import { type
|
|
18
|
+
import { type PotentiallyEmptyRArgument } from '../../r-bridge/lang-4.x/ast/model/nodes/r-function-call';
|
|
19
19
|
import { RSymbol } from '../../r-bridge/lang-4.x/ast/model/nodes/r-symbol';
|
|
20
20
|
import { type BuiltIn, NodeId } from '../../r-bridge/lang-4.x/ast/model/processing/node-id';
|
|
21
21
|
import { processLibrary } from '../internal/process/functions/call/built-in/built-in-library';
|
|
@@ -43,8 +43,9 @@ import { processRecall } from '../internal/process/functions/call/built-in/built
|
|
|
43
43
|
import { processS7NewGeneric } from '../internal/process/functions/call/built-in/built-in-s-seven-new-generic';
|
|
44
44
|
import { processS7Dispatch } from '../internal/process/functions/call/built-in/built-in-s-seven-dispatch';
|
|
45
45
|
import { BuiltInProcName } from './built-in-proc-name';
|
|
46
|
-
|
|
47
|
-
export type
|
|
46
|
+
import { processPurrrFormula } from '../internal/process/functions/call/built-in/built-in-purrr-formula';
|
|
47
|
+
export type BuiltInIdentifierProcessor = <OtherInfo>(name: RSymbol<OtherInfo & ParentInformation>, args: readonly PotentiallyEmptyRArgument<OtherInfo & ParentInformation>[], rootId: NodeId, data: DataflowProcessorInformation<OtherInfo & ParentInformation>) => DataflowInformation;
|
|
48
|
+
export type BuiltInIdentifierProcessorWithConfig<Config> = <OtherInfo>(name: RSymbol<OtherInfo & ParentInformation>, args: readonly PotentiallyEmptyRArgument<OtherInfo & ParentInformation>[], rootId: NodeId, data: DataflowProcessorInformation<OtherInfo & ParentInformation>, config: Config) => DataflowInformation;
|
|
48
49
|
export interface BuiltInIdentifierDefinition extends IdentifierReference {
|
|
49
50
|
type: ReferenceType.BuiltInFunction;
|
|
50
51
|
definedAt: BuiltIn;
|
|
@@ -81,8 +82,8 @@ export interface BuiltInEvalHandlerArgs {
|
|
|
81
82
|
blocked?: Set<NodeId>;
|
|
82
83
|
}
|
|
83
84
|
export type BuiltInEvalHandler = (args: BuiltInEvalHandlerArgs) => Value;
|
|
84
|
-
declare function defaultBuiltInProcessor<OtherInfo>(name: RSymbol<OtherInfo & ParentInformation>, args: readonly
|
|
85
|
-
declare function defaultBuiltInProcessorReadallArgs<OtherInfo>(name: RSymbol<OtherInfo & ParentInformation>, args: readonly
|
|
85
|
+
declare function defaultBuiltInProcessor<OtherInfo>(name: RSymbol<OtherInfo & ParentInformation>, args: readonly PotentiallyEmptyRArgument<OtherInfo & ParentInformation>[], rootId: NodeId, data: DataflowProcessorInformation<OtherInfo & ParentInformation>, { returnsNthArgument, useAsProcessor, forceArgs, readAllArguments, cfg, hasUnknownSideEffects, treatAsFnCall }: DefaultBuiltInProcessorConfiguration): DataflowInformation;
|
|
86
|
+
declare function defaultBuiltInProcessorReadallArgs<OtherInfo>(name: RSymbol<OtherInfo & ParentInformation>, args: readonly PotentiallyEmptyRArgument<OtherInfo & ParentInformation>[], rootId: NodeId, data: DataflowProcessorInformation<OtherInfo & ParentInformation>, { useAsProcessor, forceArgs }: Pick<DefaultBuiltInProcessorConfiguration, 'useAsProcessor' | 'forceArgs'>): DataflowInformation;
|
|
86
87
|
export declare const BuiltInProcessorMapper: {
|
|
87
88
|
readonly "builtin:access": typeof processAccess;
|
|
88
89
|
readonly "builtin:apply": typeof processApply;
|
|
@@ -100,6 +101,7 @@ export declare const BuiltInProcessorMapper: {
|
|
|
100
101
|
readonly "builtin:list": typeof processList;
|
|
101
102
|
readonly "builtin:local": typeof processLocal;
|
|
102
103
|
readonly "builtin:pipe": typeof processPipe;
|
|
104
|
+
readonly "builtin:purrr-formula": typeof processPurrrFormula;
|
|
103
105
|
readonly "builtin:quote": typeof processQuote;
|
|
104
106
|
readonly "builtin:recall": typeof processRecall;
|
|
105
107
|
readonly "builtin:register-hook": typeof processRegisterHook;
|
|
@@ -41,6 +41,7 @@ const built_in_s_seven_new_generic_1 = require("../internal/process/functions/ca
|
|
|
41
41
|
const built_in_s_seven_dispatch_1 = require("../internal/process/functions/call/built-in/built-in-s-seven-dispatch");
|
|
42
42
|
const r_string_1 = require("../../r-bridge/lang-4.x/ast/model/nodes/r-string");
|
|
43
43
|
const built_in_proc_name_1 = require("./built-in-proc-name");
|
|
44
|
+
const built_in_purrr_formula_1 = require("../internal/process/functions/call/built-in/built-in-purrr-formula");
|
|
44
45
|
function defaultBuiltInProcessor(name, args, rootId, data, { returnsNthArgument, useAsProcessor = built_in_proc_name_1.BuiltInProcName.Default, forceArgs, readAllArguments, cfg, hasUnknownSideEffects, treatAsFnCall }) {
|
|
45
46
|
const { information: res, processedArguments } = (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data, forceArgs, origin: useAsProcessor });
|
|
46
47
|
if (returnsNthArgument !== undefined) {
|
|
@@ -127,6 +128,7 @@ exports.BuiltInProcessorMapper = {
|
|
|
127
128
|
[built_in_proc_name_1.BuiltInProcName.List]: built_in_list_1.processList,
|
|
128
129
|
[built_in_proc_name_1.BuiltInProcName.Local]: built_in_local_1.processLocal,
|
|
129
130
|
[built_in_proc_name_1.BuiltInProcName.Pipe]: built_in_pipe_1.processPipe,
|
|
131
|
+
[built_in_proc_name_1.BuiltInProcName.PurrrFormula]: built_in_purrr_formula_1.processPurrrFormula,
|
|
130
132
|
[built_in_proc_name_1.BuiltInProcName.Quote]: built_in_quote_1.processQuote,
|
|
131
133
|
[built_in_proc_name_1.BuiltInProcName.Recall]: built_in_recall_1.processRecall,
|
|
132
134
|
[built_in_proc_name_1.BuiltInProcName.RegisterHook]: built_in_register_hook_1.processRegisterHook,
|