@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.
Files changed (123) hide show
  1. package/README.md +27 -16
  2. package/abstract-interpretation/absint-visitor.d.ts +13 -8
  3. package/abstract-interpretation/absint-visitor.js +35 -26
  4. package/abstract-interpretation/data-frame/dataframe-domain.d.ts +1 -2
  5. package/abstract-interpretation/data-frame/dataframe-domain.js +14 -15
  6. package/abstract-interpretation/data-frame/mappers/access-mapper.js +2 -15
  7. package/abstract-interpretation/data-frame/mappers/arguments.d.ts +11 -17
  8. package/abstract-interpretation/data-frame/mappers/arguments.js +18 -18
  9. package/abstract-interpretation/data-frame/mappers/function-mapper.d.ts +41 -15
  10. package/abstract-interpretation/data-frame/mappers/function-mapper.js +74 -48
  11. package/abstract-interpretation/data-frame/mappers/replacement-mapper.js +2 -1
  12. package/abstract-interpretation/data-frame/semantics.d.ts +1 -1
  13. package/abstract-interpretation/data-frame/semantics.js +31 -35
  14. package/abstract-interpretation/data-frame/shape-inference.js +1 -1
  15. package/abstract-interpretation/domains/interval-domain.d.ts +1 -0
  16. package/abstract-interpretation/domains/interval-domain.js +3 -0
  17. package/abstract-interpretation/domains/product-domain.d.ts +9 -0
  18. package/abstract-interpretation/domains/product-domain.js +26 -6
  19. package/abstract-interpretation/domains/state-abstract-domain.d.ts +36 -22
  20. package/abstract-interpretation/domains/state-abstract-domain.js +169 -62
  21. package/abstract-interpretation/unsupported-functions.d.ts +10 -0
  22. package/abstract-interpretation/unsupported-functions.js +45 -0
  23. package/benchmark/slicer.js +10 -13
  24. package/cli/flowr.js +1 -1
  25. package/control-flow/control-flow-graph.js +13 -9
  26. package/control-flow/semantic-cfg-guided-visitor.d.ts +6 -0
  27. package/control-flow/semantic-cfg-guided-visitor.js +6 -0
  28. package/dataflow/environments/built-in-proc-name.d.ts +6 -0
  29. package/dataflow/environments/built-in-proc-name.js +6 -0
  30. package/dataflow/environments/built-in.d.ts +7 -5
  31. package/dataflow/environments/built-in.js +2 -0
  32. package/dataflow/environments/default-builtin-config.d.ts +442 -6
  33. package/dataflow/environments/default-builtin-config.js +158 -3
  34. package/dataflow/environments/overwrite.js +2 -5
  35. package/dataflow/graph/df-helper.d.ts +14 -4
  36. package/dataflow/graph/df-helper.js +36 -6
  37. package/dataflow/graph/graph.d.ts +10 -0
  38. package/dataflow/graph/graph.js +12 -0
  39. package/dataflow/instrument/instrument-dataflow-count.d.ts +10 -0
  40. package/dataflow/instrument/instrument-dataflow-count.js +10 -0
  41. package/dataflow/internal/process/functions/call/argument/unpack-argument.d.ts +4 -4
  42. package/dataflow/internal/process/functions/call/built-in/built-in-access.d.ts +3 -3
  43. package/dataflow/internal/process/functions/call/built-in/built-in-apply.d.ts +2 -2
  44. package/dataflow/internal/process/functions/call/built-in/built-in-assignment.d.ts +3 -3
  45. package/dataflow/internal/process/functions/call/built-in/built-in-eval.d.ts +2 -2
  46. package/dataflow/internal/process/functions/call/built-in/built-in-expression-list.d.ts +2 -2
  47. package/dataflow/internal/process/functions/call/built-in/built-in-for-loop.d.ts +2 -2
  48. package/dataflow/internal/process/functions/call/built-in/built-in-function-definition.d.ts +2 -2
  49. package/dataflow/internal/process/functions/call/built-in/built-in-function-definition.js +6 -17
  50. package/dataflow/internal/process/functions/call/built-in/built-in-get.d.ts +2 -2
  51. package/dataflow/internal/process/functions/call/built-in/built-in-if-then-else.d.ts +2 -2
  52. package/dataflow/internal/process/functions/call/built-in/built-in-library.d.ts +2 -2
  53. package/dataflow/internal/process/functions/call/built-in/built-in-list.d.ts +2 -2
  54. package/dataflow/internal/process/functions/call/built-in/built-in-local.d.ts +2 -2
  55. package/dataflow/internal/process/functions/call/built-in/built-in-pipe.d.ts +23 -3
  56. package/dataflow/internal/process/functions/call/built-in/built-in-pipe.js +80 -12
  57. package/dataflow/internal/process/functions/call/built-in/built-in-purrr-formula.d.ts +41 -0
  58. package/dataflow/internal/process/functions/call/built-in/built-in-purrr-formula.js +179 -0
  59. package/dataflow/internal/process/functions/call/built-in/built-in-quote.d.ts +7 -4
  60. package/dataflow/internal/process/functions/call/built-in/built-in-quote.js +62 -1
  61. package/dataflow/internal/process/functions/call/built-in/built-in-recall.d.ts +7 -2
  62. package/dataflow/internal/process/functions/call/built-in/built-in-recall.js +15 -1
  63. package/dataflow/internal/process/functions/call/built-in/built-in-register-hook.d.ts +2 -2
  64. package/dataflow/internal/process/functions/call/built-in/built-in-repeat-loop.d.ts +2 -2
  65. package/dataflow/internal/process/functions/call/built-in/built-in-replacement.d.ts +2 -2
  66. package/dataflow/internal/process/functions/call/built-in/built-in-rm.d.ts +2 -2
  67. package/dataflow/internal/process/functions/call/built-in/built-in-s-seven-dispatch.d.ts +2 -2
  68. package/dataflow/internal/process/functions/call/built-in/built-in-s-seven-new-generic.d.ts +2 -2
  69. package/dataflow/internal/process/functions/call/built-in/built-in-s-three-dispatch.d.ts +2 -2
  70. package/dataflow/internal/process/functions/call/built-in/built-in-source.d.ts +2 -2
  71. package/dataflow/internal/process/functions/call/built-in/built-in-special-bin-op.d.ts +2 -2
  72. package/dataflow/internal/process/functions/call/built-in/built-in-stop-if-not.d.ts +2 -2
  73. package/dataflow/internal/process/functions/call/built-in/built-in-try-catch.d.ts +2 -2
  74. package/dataflow/internal/process/functions/call/built-in/built-in-vector.d.ts +2 -2
  75. package/dataflow/internal/process/functions/call/built-in/built-in-while-loop.d.ts +2 -2
  76. package/dataflow/internal/process/functions/call/common.d.ts +2 -2
  77. package/dataflow/internal/process/functions/call/common.js +4 -3
  78. package/dataflow/internal/process/functions/call/known-call-handling.d.ts +2 -2
  79. package/dataflow/internal/process/functions/call/named-call-handling.d.ts +2 -2
  80. package/documentation/wiki-absint.js +6 -5
  81. package/documentation/wiki-analyzer.js +0 -2
  82. package/documentation/wiki-linter.js +1 -0
  83. package/documentation/wiki-normalized-ast.js +7 -7
  84. package/linter/linter-rules.d.ts +24 -1
  85. package/linter/linter-rules.js +3 -1
  86. package/linter/rules/dataframe-access-validation.d.ts +1 -1
  87. package/linter/rules/dataframe-access-validation.js +3 -4
  88. package/linter/rules/roxygen-arguments.d.ts +35 -0
  89. package/linter/rules/roxygen-arguments.js +100 -0
  90. package/package.json +2 -3
  91. package/project/context/flowr-analyzer-context.d.ts +1 -8
  92. package/project/context/flowr-analyzer-context.js +1 -7
  93. package/project/context/flowr-analyzer-environment-context.d.ts +5 -0
  94. package/project/context/flowr-analyzer-environment-context.js +6 -0
  95. package/project/context/flowr-analyzer-files-context.d.ts +6 -0
  96. package/project/context/flowr-analyzer-files-context.js +4 -2
  97. package/project/flowr-analyzer-builder.js +1 -4
  98. package/queries/catalog/call-context-query/call-context-query-executor.d.ts +1 -1
  99. package/queries/catalog/call-context-query/call-context-query-executor.js +10 -5
  100. package/queries/catalog/call-context-query/call-context-query-format.d.ts +1 -1
  101. package/queries/catalog/dependencies-query/function-info/library-functions.js +2 -0
  102. package/queries/catalog/df-shape-query/df-shape-query-format.js +7 -2
  103. package/queries/catalog/files-query/files-query-executor.js +0 -1
  104. package/queries/catalog/input-sources-query/simple-input-classifier.d.ts +2 -0
  105. package/queries/catalog/input-sources-query/simple-input-classifier.js +2 -0
  106. package/r-bridge/data/data.d.ts +2 -2
  107. package/r-bridge/data/data.js +2 -2
  108. package/r-bridge/lang-4.x/ast/model/nodes/r-argument.d.ts +13 -5
  109. package/r-bridge/lang-4.x/ast/model/nodes/r-argument.js +14 -2
  110. package/r-bridge/lang-4.x/ast/model/nodes/r-function-call.d.ts +3 -3
  111. package/r-bridge/lang-4.x/ast/model/nodes/r-pipe.d.ts +9 -0
  112. package/r-bridge/lang-4.x/ast/model/nodes/r-pipe.js +13 -0
  113. package/r-bridge/lang-4.x/ast/model/versions.d.ts +2 -0
  114. package/r-bridge/lang-4.x/ast/model/versions.js +3 -1
  115. package/r-bridge/roxygen2/documentation-provider.js +15 -6
  116. package/r-bridge/roxygen2/roxygen-ast.d.ts +3 -1
  117. package/search/flowr-search-builder.js +3 -2
  118. package/util/mermaid/ast.js +2 -1
  119. package/util/record.d.ts +23 -0
  120. package/util/record.js +33 -0
  121. package/util/version.js +1 -1
  122. package/abstract-interpretation/domains/mapped-abstract-domain.d.ts +0 -41
  123. 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 as mapping of AST node IDs of a program to abstract values of an abstract domain.
8
- * The Bottom element is defined as empty mapping and the Top element is defined as mapping every existing mapped AST node ID to Top.
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 mapped_abstract_domain_1.MappedAbstractDomain {
13
- _isBottom;
14
- constructor(value, bottom) {
15
- super(value);
16
- if (bottom || value.values().some(entry => entry.isBottom())) {
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
- create(value, bottom) {
21
- return new StateAbstractDomain(value, bottom ?? this._isBottom);
29
+ static bottom(domain) {
30
+ return new StateAbstractDomain(lattice_1.Bottom, domain);
22
31
  }
23
- static top() {
24
- return new StateAbstractDomain(new Map());
32
+ get(key) {
33
+ return this.value === lattice_1.Bottom ? this.domain.bottom() : this.value.get(key);
25
34
  }
26
- get(key, ignoreBottom) {
27
- return this._isBottom && !ignoreBottom ? super.get(key)?.bottom() : super.get(key);
35
+ has(key) {
36
+ return this.value !== lattice_1.Bottom && this.value.has(key);
28
37
  }
29
38
  set(key, value) {
30
- if (value.isBottom()) {
31
- this._isBottom = true;
39
+ if (this.value === lattice_1.Bottom) {
40
+ this._value = new Map();
32
41
  }
33
- super.set(key, value);
42
+ this._value.set(key, value);
34
43
  }
35
- bottom() {
36
- return this.create(this.value, true);
44
+ remove(key) {
45
+ if (this.value !== lattice_1.Bottom) {
46
+ this._value.delete(key);
47
+ }
37
48
  }
38
49
  top() {
39
- return this.create(new Map());
50
+ return StateAbstractDomain.top(this.domain);
51
+ }
52
+ bottom() {
53
+ return StateAbstractDomain.bottom(this.domain);
40
54
  }
41
55
  equals(other) {
42
- if (this._isBottom !== other._isBottom) {
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
- return super.equals(other);
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._isBottom) {
71
+ if (this.value === other.value || this.value === lattice_1.Bottom) {
49
72
  return true;
50
73
  }
51
- else if (other._isBottom) {
74
+ else if (other.value === lattice_1.Bottom || this.value.size > other.value.size) {
52
75
  return false;
53
76
  }
54
- return super.leq(other);
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._isBottom) {
58
- return other.create(other.value);
86
+ if (this.value === lattice_1.Bottom) {
87
+ return this.create(other.value);
59
88
  }
60
- else if (other._isBottom) {
89
+ else if (other.value === lattice_1.Bottom) {
61
90
  return this.create(this.value);
62
91
  }
63
- return super.join(other);
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
- const result = super.meet(other);
67
- result._isBottom = this._isBottom || other._isBottom;
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._isBottom) {
72
- return other.create(other.value);
123
+ if (this.value === lattice_1.Bottom) {
124
+ return this.create(other.value);
73
125
  }
74
- else if (other._isBottom) {
126
+ else if (other.value === lattice_1.Bottom) {
75
127
  return this.create(this.value);
76
128
  }
77
- return super.widen(other);
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
- const result = super.narrow(other);
81
- result._isBottom = this._isBottom || other._isBottom;
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._isBottom) {
160
+ if (this.value === lattice_1.Bottom) {
86
161
  return new Set();
87
162
  }
88
- else if (this.value.size === 0) {
89
- return lattice_1.Top;
90
- }
91
- return super.concretize(limit);
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.create(new Map(), true);
99
- }
100
- return super.abstract(concrete);
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._isBottom) {
104
- return lattice_1.BottomSymbol;
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 super.toJson();
213
+ return Object.fromEntries(this.value.entries().map(([key, value]) => [key, value.toJson()]));
110
214
  }
111
215
  toString() {
112
- if (this._isBottom) {
216
+ if (this.value === lattice_1.Bottom) {
113
217
  return lattice_1.BottomSymbol;
114
218
  }
115
- else if (this.value.size === 0) {
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._isBottom ?? false;
225
+ return this.value == lattice_1.Bottom;
125
226
  }
126
227
  isValue() {
127
- return !this._isBottom;
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
@@ -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)([inference.getAbstractTrace()]);
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: inference.getAbstractState(node.info.id)?.value.size ?? 0
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.value.range === lattice_1.Top ? Infinity : value.value.range.size;
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 instanceof set_range_domain_1.SetRangeDomain) {
339
- if (value.value.range === lattice_1.Top) {
340
- return 'infinite';
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: analyzer, allowRSessionAccess });
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) ?? new Map();
593
- if (!this.edgeInfos.has(from)) {
594
- this.edgeInfos.set(from, edgesFrom);
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
- edgesFrom.set(to, edge);
597
- const edgesTo = this.revEdgeInfos.get(to) ?? new Map();
598
- if (!this.revEdgeInfos.has(to)) {
599
- this.revEdgeInfos.set(to, edgesTo);
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 ? false : roots.has(id));
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 RFunctionArgument } from '../../r-bridge/lang-4.x/ast/model/nodes/r-function-call';
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
- export type BuiltInIdentifierProcessor = <OtherInfo>(name: RSymbol<OtherInfo & ParentInformation>, args: readonly RFunctionArgument<OtherInfo & ParentInformation>[], rootId: NodeId, data: DataflowProcessorInformation<OtherInfo & ParentInformation>) => DataflowInformation;
47
- export type BuiltInIdentifierProcessorWithConfig<Config> = <OtherInfo>(name: RSymbol<OtherInfo & ParentInformation>, args: readonly RFunctionArgument<OtherInfo & ParentInformation>[], rootId: NodeId, data: DataflowProcessorInformation<OtherInfo & ParentInformation>, config: Config) => DataflowInformation;
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 RFunctionArgument<OtherInfo & ParentInformation>[], rootId: NodeId, data: DataflowProcessorInformation<OtherInfo & ParentInformation>, { returnsNthArgument, useAsProcessor, forceArgs, readAllArguments, cfg, hasUnknownSideEffects, treatAsFnCall }: DefaultBuiltInProcessorConfiguration): DataflowInformation;
85
- declare function defaultBuiltInProcessorReadallArgs<OtherInfo>(name: RSymbol<OtherInfo & ParentInformation>, args: readonly RFunctionArgument<OtherInfo & ParentInformation>[], rootId: NodeId, data: DataflowProcessorInformation<OtherInfo & ParentInformation>, { useAsProcessor, forceArgs }: Pick<DefaultBuiltInProcessorConfiguration, 'useAsProcessor' | 'forceArgs'>): DataflowInformation;
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,