@eagleoutice/flowr 2.9.14 → 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 (214) hide show
  1. package/README.md +52 -29
  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/benchmark/stats/stats.d.ts +2 -2
  25. package/cli/flowr.js +1 -1
  26. package/cli/repl/parser/slice-query-parser.d.ts +2 -2
  27. package/config.d.ts +4 -0
  28. package/config.js +5 -3
  29. package/control-flow/control-flow-graph.js +13 -9
  30. package/control-flow/semantic-cfg-guided-visitor.d.ts +6 -0
  31. package/control-flow/semantic-cfg-guided-visitor.js +6 -0
  32. package/dataflow/environments/built-in-proc-name.d.ts +6 -0
  33. package/dataflow/environments/built-in-proc-name.js +6 -0
  34. package/dataflow/environments/built-in.d.ts +7 -5
  35. package/dataflow/environments/built-in.js +2 -0
  36. package/dataflow/environments/default-builtin-config.d.ts +442 -6
  37. package/dataflow/environments/default-builtin-config.js +158 -3
  38. package/dataflow/environments/identifier.d.ts +4 -0
  39. package/dataflow/environments/identifier.js +17 -0
  40. package/dataflow/environments/overwrite.js +2 -5
  41. package/dataflow/graph/call-graph.d.ts +4 -7
  42. package/dataflow/graph/call-graph.js +0 -22
  43. package/dataflow/graph/df-helper.d.ts +23 -12
  44. package/dataflow/graph/df-helper.js +44 -7
  45. package/dataflow/graph/graph-helper.d.ts +9 -4
  46. package/dataflow/graph/graph-helper.js +26 -3
  47. package/dataflow/graph/graph.d.ts +23 -2
  48. package/dataflow/graph/graph.js +38 -4
  49. package/dataflow/graph/vertex.d.ts +2 -0
  50. package/dataflow/instrument/instrument-dataflow-count.d.ts +10 -0
  51. package/dataflow/instrument/instrument-dataflow-count.js +10 -0
  52. package/dataflow/internal/process/functions/call/argument/unpack-argument.d.ts +4 -4
  53. package/dataflow/internal/process/functions/call/built-in/built-in-access.d.ts +3 -3
  54. package/dataflow/internal/process/functions/call/built-in/built-in-apply.d.ts +2 -2
  55. package/dataflow/internal/process/functions/call/built-in/built-in-apply.js +1 -0
  56. package/dataflow/internal/process/functions/call/built-in/built-in-assignment.d.ts +3 -3
  57. package/dataflow/internal/process/functions/call/built-in/built-in-assignment.js +1 -1
  58. package/dataflow/internal/process/functions/call/built-in/built-in-eval.d.ts +2 -2
  59. package/dataflow/internal/process/functions/call/built-in/built-in-expression-list.d.ts +2 -2
  60. package/dataflow/internal/process/functions/call/built-in/built-in-for-loop.d.ts +2 -2
  61. package/dataflow/internal/process/functions/call/built-in/built-in-for-loop.js +1 -1
  62. package/dataflow/internal/process/functions/call/built-in/built-in-function-definition.d.ts +2 -2
  63. package/dataflow/internal/process/functions/call/built-in/built-in-function-definition.js +8 -19
  64. package/dataflow/internal/process/functions/call/built-in/built-in-get.d.ts +2 -2
  65. package/dataflow/internal/process/functions/call/built-in/built-in-if-then-else.d.ts +2 -2
  66. package/dataflow/internal/process/functions/call/built-in/built-in-library.d.ts +2 -2
  67. package/dataflow/internal/process/functions/call/built-in/built-in-list.d.ts +2 -2
  68. package/dataflow/internal/process/functions/call/built-in/built-in-local.d.ts +2 -2
  69. package/dataflow/internal/process/functions/call/built-in/built-in-pipe.d.ts +23 -3
  70. package/dataflow/internal/process/functions/call/built-in/built-in-pipe.js +80 -12
  71. package/dataflow/internal/process/functions/call/built-in/built-in-purrr-formula.d.ts +41 -0
  72. package/dataflow/internal/process/functions/call/built-in/built-in-purrr-formula.js +179 -0
  73. package/dataflow/internal/process/functions/call/built-in/built-in-quote.d.ts +7 -4
  74. package/dataflow/internal/process/functions/call/built-in/built-in-quote.js +62 -1
  75. package/dataflow/internal/process/functions/call/built-in/built-in-recall.d.ts +7 -2
  76. package/dataflow/internal/process/functions/call/built-in/built-in-recall.js +15 -1
  77. package/dataflow/internal/process/functions/call/built-in/built-in-register-hook.d.ts +2 -2
  78. package/dataflow/internal/process/functions/call/built-in/built-in-repeat-loop.d.ts +2 -2
  79. package/dataflow/internal/process/functions/call/built-in/built-in-replacement.d.ts +2 -2
  80. package/dataflow/internal/process/functions/call/built-in/built-in-rm.d.ts +2 -2
  81. package/dataflow/internal/process/functions/call/built-in/built-in-s-seven-dispatch.d.ts +2 -2
  82. package/dataflow/internal/process/functions/call/built-in/built-in-s-seven-new-generic.d.ts +2 -2
  83. package/dataflow/internal/process/functions/call/built-in/built-in-s-three-dispatch.d.ts +2 -2
  84. package/dataflow/internal/process/functions/call/built-in/built-in-source.d.ts +2 -2
  85. package/dataflow/internal/process/functions/call/built-in/built-in-special-bin-op.d.ts +2 -2
  86. package/dataflow/internal/process/functions/call/built-in/built-in-stop-if-not.d.ts +2 -2
  87. package/dataflow/internal/process/functions/call/built-in/built-in-try-catch.d.ts +2 -2
  88. package/dataflow/internal/process/functions/call/built-in/built-in-vector.d.ts +2 -2
  89. package/dataflow/internal/process/functions/call/built-in/built-in-while-loop.d.ts +2 -2
  90. package/dataflow/internal/process/functions/call/common.d.ts +2 -2
  91. package/dataflow/internal/process/functions/call/common.js +6 -4
  92. package/dataflow/internal/process/functions/call/known-call-handling.d.ts +2 -2
  93. package/dataflow/internal/process/functions/call/named-call-handling.d.ts +2 -2
  94. package/dataflow/internal/process/functions/process-parameter.js +1 -1
  95. package/documentation/doc-readme.js +2 -1
  96. package/documentation/wiki-absint.js +6 -5
  97. package/documentation/wiki-analyzer.js +0 -2
  98. package/documentation/wiki-linter.js +6 -0
  99. package/documentation/wiki-normalized-ast.js +7 -7
  100. package/linter/linter-rules.d.ts +49 -1
  101. package/linter/linter-rules.js +5 -1
  102. package/linter/rules/dataframe-access-validation.d.ts +1 -1
  103. package/linter/rules/dataframe-access-validation.js +3 -4
  104. package/linter/rules/problematic-eval.d.ts +44 -0
  105. package/linter/rules/problematic-eval.js +83 -0
  106. package/linter/rules/roxygen-arguments.d.ts +35 -0
  107. package/linter/rules/roxygen-arguments.js +100 -0
  108. package/package.json +8 -9
  109. package/project/context/flowr-analyzer-context.d.ts +1 -8
  110. package/project/context/flowr-analyzer-context.js +1 -7
  111. package/project/context/flowr-analyzer-environment-context.d.ts +5 -0
  112. package/project/context/flowr-analyzer-environment-context.js +6 -0
  113. package/project/context/flowr-analyzer-files-context.d.ts +6 -0
  114. package/project/context/flowr-analyzer-files-context.js +4 -2
  115. package/project/flowr-analyzer-builder.js +1 -4
  116. package/queries/catalog/call-context-query/call-context-query-executor.d.ts +1 -1
  117. package/queries/catalog/call-context-query/call-context-query-executor.js +10 -5
  118. package/queries/catalog/call-context-query/call-context-query-format.d.ts +1 -1
  119. package/queries/catalog/dependencies-query/function-info/library-functions.js +2 -0
  120. package/queries/catalog/df-shape-query/df-shape-query-executor.js +1 -1
  121. package/queries/catalog/df-shape-query/df-shape-query-format.d.ts +3 -3
  122. package/queries/catalog/df-shape-query/df-shape-query-format.js +7 -2
  123. package/queries/catalog/does-call-query/does-call-query-executor.js +1 -1
  124. package/queries/catalog/does-call-query/does-call-query-format.d.ts +2 -2
  125. package/queries/catalog/files-query/files-query-executor.js +0 -1
  126. package/queries/catalog/happens-before-query/happens-before-query-executor.js +2 -2
  127. package/queries/catalog/happens-before-query/happens-before-query-format.d.ts +3 -3
  128. package/queries/catalog/input-sources-query/input-sources-query-executor.d.ts +6 -0
  129. package/queries/catalog/input-sources-query/input-sources-query-executor.js +66 -0
  130. package/queries/catalog/input-sources-query/input-sources-query-format.d.ts +36 -0
  131. package/queries/catalog/input-sources-query/input-sources-query-format.js +63 -0
  132. package/queries/catalog/input-sources-query/simple-input-classifier.d.ts +92 -0
  133. package/queries/catalog/input-sources-query/simple-input-classifier.js +310 -0
  134. package/queries/catalog/inspect-exceptions-query/inspect-exception-query-executor.d.ts +2 -2
  135. package/queries/catalog/inspect-exceptions-query/inspect-exception-query-executor.js +1 -1
  136. package/queries/catalog/inspect-exceptions-query/inspect-exception-query-format.d.ts +2 -2
  137. package/queries/catalog/inspect-higher-order-query/inspect-higher-order-query-executor.js +1 -1
  138. package/queries/catalog/inspect-higher-order-query/inspect-higher-order-query-format.d.ts +2 -2
  139. package/queries/catalog/inspect-recursion-query/inspect-recursion-query-format.d.ts +2 -2
  140. package/queries/catalog/location-map-query/location-map-query-executor.js +1 -1
  141. package/queries/catalog/location-map-query/location-map-query-format.d.ts +2 -2
  142. package/queries/catalog/origin-query/origin-query-executor.d.ts +2 -2
  143. package/queries/catalog/origin-query/origin-query-executor.js +1 -1
  144. package/queries/catalog/origin-query/origin-query-format.d.ts +3 -3
  145. package/queries/catalog/provenance-query/provenance-query-executor.d.ts +1 -4
  146. package/queries/catalog/provenance-query/provenance-query-executor.js +3 -6
  147. package/queries/catalog/provenance-query/provenance-query-format.d.ts +2 -2
  148. package/queries/catalog/resolve-value-query/resolve-value-query-executor.js +1 -1
  149. package/queries/query.d.ts +9 -1
  150. package/queries/query.js +2 -0
  151. package/r-bridge/data/data.d.ts +2 -2
  152. package/r-bridge/data/data.js +2 -2
  153. package/r-bridge/lang-4.x/ast/model/model.d.ts +3 -0
  154. package/r-bridge/lang-4.x/ast/model/model.js +3 -0
  155. package/r-bridge/lang-4.x/ast/model/nodes/r-access.d.ts +16 -1
  156. package/r-bridge/lang-4.x/ast/model/nodes/r-access.js +2 -0
  157. package/r-bridge/lang-4.x/ast/model/nodes/r-argument.d.ts +29 -6
  158. package/r-bridge/lang-4.x/ast/model/nodes/r-argument.js +16 -2
  159. package/r-bridge/lang-4.x/ast/model/nodes/r-binary-op.d.ts +16 -1
  160. package/r-bridge/lang-4.x/ast/model/nodes/r-binary-op.js +2 -0
  161. package/r-bridge/lang-4.x/ast/model/nodes/r-break.d.ts +15 -0
  162. package/r-bridge/lang-4.x/ast/model/nodes/r-break.js +2 -0
  163. package/r-bridge/lang-4.x/ast/model/nodes/r-comment.d.ts +15 -0
  164. package/r-bridge/lang-4.x/ast/model/nodes/r-comment.js +2 -0
  165. package/r-bridge/lang-4.x/ast/model/nodes/r-expression-list.d.ts +16 -1
  166. package/r-bridge/lang-4.x/ast/model/nodes/r-expression-list.js +2 -0
  167. package/r-bridge/lang-4.x/ast/model/nodes/r-for-loop.d.ts +16 -1
  168. package/r-bridge/lang-4.x/ast/model/nodes/r-for-loop.js +2 -0
  169. package/r-bridge/lang-4.x/ast/model/nodes/r-function-call.d.ts +19 -4
  170. package/r-bridge/lang-4.x/ast/model/nodes/r-function-call.js +2 -0
  171. package/r-bridge/lang-4.x/ast/model/nodes/r-function-definition.d.ts +21 -0
  172. package/r-bridge/lang-4.x/ast/model/nodes/r-function-definition.js +16 -0
  173. package/r-bridge/lang-4.x/ast/model/nodes/r-if-then-else.d.ts +16 -1
  174. package/r-bridge/lang-4.x/ast/model/nodes/r-if-then-else.js +2 -0
  175. package/r-bridge/lang-4.x/ast/model/nodes/r-line-directive.d.ts +16 -1
  176. package/r-bridge/lang-4.x/ast/model/nodes/r-line-directive.js +2 -0
  177. package/r-bridge/lang-4.x/ast/model/nodes/r-logical.d.ts +16 -1
  178. package/r-bridge/lang-4.x/ast/model/nodes/r-logical.js +2 -0
  179. package/r-bridge/lang-4.x/ast/model/nodes/r-next.d.ts +16 -1
  180. package/r-bridge/lang-4.x/ast/model/nodes/r-next.js +2 -0
  181. package/r-bridge/lang-4.x/ast/model/nodes/r-number.d.ts +16 -1
  182. package/r-bridge/lang-4.x/ast/model/nodes/r-number.js +2 -0
  183. package/r-bridge/lang-4.x/ast/model/nodes/r-parameter.d.ts +16 -1
  184. package/r-bridge/lang-4.x/ast/model/nodes/r-parameter.js +2 -0
  185. package/r-bridge/lang-4.x/ast/model/nodes/r-pipe.d.ts +25 -1
  186. package/r-bridge/lang-4.x/ast/model/nodes/r-pipe.js +15 -0
  187. package/r-bridge/lang-4.x/ast/model/nodes/r-repeat-loop.d.ts +16 -1
  188. package/r-bridge/lang-4.x/ast/model/nodes/r-repeat-loop.js +2 -0
  189. package/r-bridge/lang-4.x/ast/model/nodes/r-string.d.ts +16 -1
  190. package/r-bridge/lang-4.x/ast/model/nodes/r-string.js +2 -0
  191. package/r-bridge/lang-4.x/ast/model/nodes/r-symbol.d.ts +16 -1
  192. package/r-bridge/lang-4.x/ast/model/nodes/r-symbol.js +2 -0
  193. package/r-bridge/lang-4.x/ast/model/nodes/r-unary-op.d.ts +16 -1
  194. package/r-bridge/lang-4.x/ast/model/nodes/r-unary-op.js +2 -0
  195. package/r-bridge/lang-4.x/ast/model/nodes/r-while-loop.d.ts +16 -1
  196. package/r-bridge/lang-4.x/ast/model/nodes/r-while-loop.js +2 -0
  197. package/r-bridge/lang-4.x/ast/model/versions.d.ts +2 -0
  198. package/r-bridge/lang-4.x/ast/model/versions.js +3 -1
  199. package/r-bridge/roxygen2/documentation-provider.js +15 -6
  200. package/r-bridge/roxygen2/roxygen-ast.d.ts +3 -1
  201. package/search/flowr-search-builder.js +3 -2
  202. package/search/search-executor/search-generators.js +1 -1
  203. package/slicing/criterion/parse.d.ts +11 -10
  204. package/slicing/criterion/parse.js +9 -8
  205. package/slicing/static/static-slicer.js +24 -1
  206. package/util/collections/arrays.d.ts +4 -0
  207. package/util/collections/arrays.js +7 -0
  208. package/util/mermaid/ast.js +2 -1
  209. package/util/mermaid/dfg.js +2 -1
  210. package/util/record.d.ts +23 -0
  211. package/util/record.js +33 -0
  212. package/util/version.js +1 -1
  213. package/abstract-interpretation/domains/mapped-abstract-domain.d.ts +0 -41
  214. package/abstract-interpretation/domains/mapped-abstract-domain.js +0 -213
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ProductDomain = void 0;
4
4
  const abstract_domain_1 = require("./abstract-domain");
5
5
  const lattice_1 = require("./lattice");
6
+ const record_1 = require("../../util/record");
6
7
  /**
7
8
  * A product abstract domain as named Cartesian product of sub abstract domains.
8
9
  * The sub abstract domains are represented by a record mapping property names to abstract domains.
@@ -10,6 +11,10 @@ const lattice_1 = require("./lattice");
10
11
  * @template Product - Type of the abstract product of the product domain mapping property names to abstract domains
11
12
  */
12
13
  class ProductDomain extends abstract_domain_1.AbstractDomain {
14
+ constructor(value) {
15
+ super(record_1.Record.mapProperties(value, entry => entry.create(entry.value)));
16
+ this._value = this.reduce(this.value);
17
+ }
13
18
  bottom() {
14
19
  const result = this.create(this.value);
15
20
  for (const key in result.value) {
@@ -51,28 +56,28 @@ class ProductDomain extends abstract_domain_1.AbstractDomain {
51
56
  for (const key in result.value) {
52
57
  result._value[key] = result.value[key].join(other.value[key]);
53
58
  }
54
- return result;
59
+ return result.refine();
55
60
  }
56
61
  meet(other) {
57
62
  const result = this.create(this.value);
58
63
  for (const key in result.value) {
59
64
  result._value[key] = result.value[key].meet(other.value[key]);
60
65
  }
61
- return result;
66
+ return result.refine();
62
67
  }
63
68
  widen(other) {
64
69
  const result = this.create(this.value);
65
70
  for (const key in result.value) {
66
71
  result._value[key] = result.value[key].widen(other.value[key]);
67
72
  }
68
- return result;
73
+ return result.refine();
69
74
  }
70
75
  narrow(other) {
71
76
  const result = this.create(this.value);
72
77
  for (const key in result.value) {
73
78
  result._value[key] = result.value[key].narrow(other.value[key]);
74
79
  }
75
- return result;
80
+ return result.refine();
76
81
  }
77
82
  concretize(limit) {
78
83
  let result = new Set([{}]);
@@ -103,10 +108,10 @@ class ProductDomain extends abstract_domain_1.AbstractDomain {
103
108
  const concreteValues = new Set(concrete.values().map(value => value[key]));
104
109
  result._value[key] = result.value[key].abstract(concreteValues);
105
110
  }
106
- return result;
111
+ return result.refine();
107
112
  }
108
113
  toJson() {
109
- return Object.fromEntries(Object.entries(this.value).map(([key, value]) => [key, value.toJson()]));
114
+ return record_1.Record.mapProperties(this.value, entry => entry.toJson());
110
115
  }
111
116
  toString() {
112
117
  return '(' + Object.entries(this.value).map(([key, value]) => `${key}: ${value.toString()}`).join(', ') + ')';
@@ -120,6 +125,21 @@ class ProductDomain extends abstract_domain_1.AbstractDomain {
120
125
  isValue() {
121
126
  return true;
122
127
  }
128
+ /**
129
+ * Optional reduction function for a reduced product domain.
130
+ */
131
+ reduce(value) {
132
+ return value;
133
+ }
134
+ refine() {
135
+ if (!this.isTop() || this.isBottom()) {
136
+ const reduced = this.reduce(this.value);
137
+ if (reduced !== this.value) {
138
+ return this.create(reduced);
139
+ }
140
+ }
141
+ return this;
142
+ }
123
143
  }
124
144
  exports.ProductDomain = ProductDomain;
125
145
  //# sourceMappingURL=product-domain.js.map
@@ -1,42 +1,55 @@
1
1
  import type { NodeId } from '../../r-bridge/lang-4.x/ast/model/processing/node-id';
2
- import type { AnyAbstractDomain } from './abstract-domain';
3
- import { Top } from './lattice';
4
- import type { ConcreteMap } from './mapped-abstract-domain';
5
- import { MappedAbstractDomain } from './mapped-abstract-domain';
2
+ import { AbstractDomain, type AnyAbstractDomain, type ConcreteDomain } from './abstract-domain';
3
+ import { Bottom, Top } from './lattice';
4
+ /** The type of the concrete state of the concrete domain of a state abstract domain that maps keys to a concrete value in the concrete domain */
5
+ export type ConcreteState<Domain extends AnyAbstractDomain> = ReadonlyMap<NodeId, ConcreteDomain<Domain>>;
6
+ /** The type of the actual values of the state abstract domain as map of keys to domain values */
7
+ type StateDomainValue<Domain extends AnyAbstractDomain> = ReadonlyMap<NodeId, Domain>;
8
+ /** The type of the Top element of the state abstract domain as (empty) map of keys to domain values */
9
+ type StateDomainTop = ReadonlyMap<NodeId, never>;
10
+ /** The type of the Bottom element of the state abstract domain as {@link Bottom} symbol */
11
+ type StateDomainBottom = typeof Bottom;
12
+ /** The type of the abstract values of the state abstract domain that are Top, Bottom, or actual values */
13
+ type StateDomainLift<Domain extends AnyAbstractDomain> = StateDomainValue<Domain> | StateDomainBottom;
6
14
  /**
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
15
+ * A state abstract domain that maps AST node IDs of a program to abstract values of an abstract domain.
16
+ * The Bottom element is defined as {@link Bottom} symbol and the Top element as empty mapping.
17
+ * @template Domain - Type of the value abstract domain to map the AST node IDs to
10
18
  * @see {@link NodeId} for the node IDs of the AST nodes
11
19
  */
12
- export declare class StateAbstractDomain<Domain extends AnyAbstractDomain> extends MappedAbstractDomain<NodeId, Domain> {
13
- private _isBottom;
14
- constructor(value: ReadonlyMap<NodeId, Domain>, bottom?: boolean);
15
- create(value: ReadonlyMap<NodeId, Domain>, bottom?: boolean): this;
16
- static top<Domain extends AnyAbstractDomain>(): StateAbstractDomain<Domain>;
17
- get(key: NodeId, ignoreBottom?: boolean): Domain | undefined;
20
+ export declare class StateAbstractDomain<Domain extends AnyAbstractDomain, Value extends StateDomainLift<Domain> = StateDomainLift<Domain>> extends AbstractDomain<ConcreteState<Domain>, StateDomainValue<Domain>, StateDomainTop, StateDomainBottom, Value> {
21
+ protected domain: Domain;
22
+ constructor(value: Value, domain: Domain);
23
+ create(value: StateDomainLift<Domain>): this;
24
+ static top<Domain extends AnyAbstractDomain>(domain: Domain): StateAbstractDomain<Domain, StateDomainTop>;
25
+ static bottom<Domain extends AnyAbstractDomain>(domain: Domain): StateAbstractDomain<Domain, StateDomainBottom>;
26
+ get(key: NodeId): Domain | undefined;
27
+ has(key: NodeId): boolean;
18
28
  protected set(key: NodeId, value: Domain): void;
19
- bottom(): this;
20
- top(): this;
29
+ protected remove(key: NodeId): void;
30
+ top(): this & StateAbstractDomain<Domain, StateDomainTop>;
31
+ bottom(): this & StateAbstractDomain<Domain, StateDomainBottom>;
21
32
  equals(other: this): boolean;
22
33
  leq(other: this): boolean;
23
34
  join(other: this): this;
24
35
  meet(other: this): this;
25
36
  widen(other: this): this;
26
37
  narrow(other: this): this;
27
- concretize(limit: number): ReadonlySet<ConcreteMap<NodeId, Domain>> | typeof Top;
28
- abstract(concrete: typeof Top | ReadonlySet<ConcreteMap<NodeId, Domain>>): this;
38
+ concretize(limit: number): ReadonlySet<ConcreteState<Domain>> | typeof Top;
39
+ abstract(concrete: ReadonlySet<ConcreteState<Domain>> | typeof Top): this;
29
40
  toJson(): unknown;
30
41
  toString(): string;
31
- isTop(): this is this;
32
- isBottom(): this is this;
33
- isValue(): this is this;
42
+ isTop(): this is this & StateAbstractDomain<Domain, StateDomainTop>;
43
+ isBottom(): this is this & StateAbstractDomain<Domain, StateDomainBottom>;
44
+ isValue(): this is this & StateAbstractDomain<Domain, StateDomainValue<Domain>>;
34
45
  }
35
46
  /**
36
47
  * A mutable version of the {@link StateAbstractDomain} with {@link MutableStateAbstractDomain#set|`set`} and {@link MutableStateAbstractDomain#remove|`remove`}.
37
48
  */
38
- export declare class MutableStateAbstractDomain<Domain extends AnyAbstractDomain> extends StateAbstractDomain<Domain> {
39
- create(value: ReadonlyMap<NodeId, Domain>): this;
49
+ export declare class MutableStateAbstractDomain<Domain extends AnyAbstractDomain, Value extends StateDomainLift<Domain> = StateDomainLift<Domain>> extends StateAbstractDomain<Domain, Value> {
50
+ create(value: StateDomainLift<Domain>): this;
51
+ static top<Domain extends AnyAbstractDomain>(domain: Domain): MutableStateAbstractDomain<Domain, StateDomainTop>;
52
+ static bottom<Domain extends AnyAbstractDomain>(domain: Domain): MutableStateAbstractDomain<Domain, StateDomainBottom>;
40
53
  set(key: NodeId, value: Domain): void;
41
54
  remove(key: NodeId): void;
42
55
  }
@@ -45,3 +58,4 @@ export declare class MutableStateAbstractDomain<Domain extends AnyAbstractDomain
45
58
  * @template StateDomain - The state abstract domain to get the value abstract domain type for
46
59
  */
47
60
  export type ValueAbstractDomain<StateDomain extends StateAbstractDomain<AnyAbstractDomain>> = StateDomain extends StateAbstractDomain<infer Domain> ? Domain : never;
61
+ export {};
@@ -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
  }
@@ -1,4 +1,4 @@
1
- import type { SingleSlicingCriterion, SlicingCriteria } from '../../slicing/criterion/parse';
1
+ import type { SlicingCriterion, SlicingCriteria } from '../../slicing/criterion/parse';
2
2
  import type { NodeId } from '../../r-bridge/lang-4.x/ast/model/processing/node-id';
3
3
  import type { ReconstructionResult } from '../../reconstruct/reconstruct';
4
4
  import type { RParseRequestFromFile, RParseRequestFromText } from '../../r-bridge/retriever';
@@ -15,7 +15,7 @@ export type ElapsedTime = bigint;
15
15
  export interface PerSliceStats {
16
16
  measurements: Map<PerSliceMeasurements, ElapsedTime>;
17
17
  slicingCriteria: {
18
- criterion: SingleSlicingCriterion;
18
+ criterion: SlicingCriterion;
19
19
  id: NodeId;
20
20
  }[];
21
21
  reconstructedCode: ReconstructionResult;
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
  }
@@ -1,4 +1,4 @@
1
- import type { SingleSlicingCriterion, SlicingCriteria } from '../../../slicing/criterion/parse';
1
+ import type { SlicingCriterion, SlicingCriteria } from '../../../slicing/criterion/parse';
2
2
  import { SliceDirection } from '../../../util/slice-direction';
3
3
  /**
4
4
  * Checks whether the given argument represents a slicing direction with an `f` suffix.
@@ -7,7 +7,7 @@ export declare function sliceDirectionParser(argument: string): SliceDirection;
7
7
  /**
8
8
  * Parses a single slicing criterion from the given argument.
9
9
  */
10
- export declare function sliceCriterionParser(argument: string | undefined): SingleSlicingCriterion | undefined;
10
+ export declare function sliceCriterionParser(argument: string | undefined): SlicingCriterion | undefined;
11
11
  /**
12
12
  * Parses multiple slicing criteria from the given argument.
13
13
  */
package/config.d.ts CHANGED
@@ -159,6 +159,10 @@ export interface FlowrConfig extends MergeableRecord {
159
159
  * The maximum number of iterations to perform on a single function call during slicing
160
160
  */
161
161
  readonly threshold?: number;
162
+ /**
163
+ * If set, the slicer will gain an additional post-pass
164
+ */
165
+ readonly autoExtend?: boolean;
162
166
  };
163
167
  };
164
168
  /**