@eagleoutice/flowr 2.2.14 → 2.2.16

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 (245) hide show
  1. package/README.md +210 -6
  2. package/benchmark/slicer.d.ts +3 -1
  3. package/benchmark/slicer.js +8 -5
  4. package/benchmark/summarizer/first-phase/process.d.ts +2 -1
  5. package/benchmark/summarizer/first-phase/process.js +2 -2
  6. package/cli/benchmark-app.d.ts +1 -0
  7. package/cli/benchmark-app.js +4 -1
  8. package/cli/benchmark-helper-app.d.ts +1 -0
  9. package/cli/benchmark-helper-app.js +7 -8
  10. package/cli/common/options.js +2 -0
  11. package/cli/export-quads-app.js +2 -1
  12. package/cli/flowr.js +58 -57
  13. package/cli/repl/commands/repl-cfg.js +13 -13
  14. package/cli/repl/commands/repl-commands.js +3 -3
  15. package/cli/repl/commands/repl-dataflow.js +10 -10
  16. package/cli/repl/commands/repl-execute.d.ts +2 -3
  17. package/cli/repl/commands/repl-execute.js +5 -4
  18. package/cli/repl/commands/repl-lineage.js +4 -4
  19. package/cli/repl/commands/repl-main.d.ts +12 -1
  20. package/cli/repl/commands/repl-normalize.js +6 -6
  21. package/cli/repl/commands/repl-parse.js +2 -2
  22. package/cli/repl/commands/repl-query.js +9 -9
  23. package/cli/repl/commands/repl-version.js +1 -1
  24. package/cli/repl/core.d.ts +5 -2
  25. package/cli/repl/core.js +10 -8
  26. package/cli/repl/server/connection.d.ts +3 -1
  27. package/cli/repl/server/connection.js +7 -5
  28. package/cli/repl/server/server.d.ts +3 -2
  29. package/cli/repl/server/server.js +4 -2
  30. package/cli/script-core/statistics-core.d.ts +2 -1
  31. package/cli/script-core/statistics-core.js +2 -2
  32. package/cli/script-core/statistics-helper-core.d.ts +2 -1
  33. package/cli/script-core/statistics-helper-core.js +5 -4
  34. package/cli/slicer-app.js +4 -2
  35. package/cli/statistics-app.js +2 -1
  36. package/cli/statistics-helper-app.js +2 -1
  37. package/config.d.ts +12 -10
  38. package/config.js +27 -43
  39. package/control-flow/basic-cfg-guided-visitor.d.ts +3 -3
  40. package/control-flow/cfg-dead-code.d.ts +4 -0
  41. package/control-flow/cfg-dead-code.js +124 -0
  42. package/control-flow/cfg-simplification.d.ts +19 -6
  43. package/control-flow/cfg-simplification.js +23 -19
  44. package/control-flow/control-flow-graph.d.ts +3 -1
  45. package/control-flow/control-flow-graph.js +5 -0
  46. package/control-flow/dfg-cfg-guided-visitor.d.ts +9 -7
  47. package/control-flow/dfg-cfg-guided-visitor.js +16 -5
  48. package/control-flow/extract-cfg.d.ts +4 -2
  49. package/control-flow/extract-cfg.js +63 -59
  50. package/control-flow/semantic-cfg-guided-visitor.d.ts +36 -9
  51. package/control-flow/semantic-cfg-guided-visitor.js +73 -20
  52. package/control-flow/simple-visitor.d.ts +4 -0
  53. package/control-flow/simple-visitor.js +14 -0
  54. package/control-flow/syntax-cfg-guided-visitor.d.ts +2 -2
  55. package/core/pipeline-executor.d.ts +4 -1
  56. package/core/pipeline-executor.js +6 -5
  57. package/core/steps/all/core/10-normalize.d.ts +2 -0
  58. package/core/steps/all/core/10-normalize.js +1 -1
  59. package/core/steps/all/core/11-normalize-tree-sitter.d.ts +2 -1
  60. package/core/steps/all/core/11-normalize-tree-sitter.js +2 -2
  61. package/core/steps/all/core/20-dataflow.d.ts +2 -1
  62. package/core/steps/all/core/20-dataflow.js +2 -2
  63. package/core/steps/all/static-slicing/00-slice.d.ts +2 -1
  64. package/core/steps/all/static-slicing/00-slice.js +2 -2
  65. package/core/steps/pipeline/default-pipelines.d.ts +32 -31
  66. package/core/steps/pipeline/default-pipelines.js +8 -8
  67. package/core/steps/pipeline-step.d.ts +2 -1
  68. package/dataflow/environments/built-in-config.d.ts +4 -3
  69. package/dataflow/environments/built-in.d.ts +16 -1
  70. package/dataflow/environments/built-in.js +11 -5
  71. package/dataflow/environments/default-builtin-config.js +5 -3
  72. package/dataflow/environments/define.d.ts +2 -1
  73. package/dataflow/environments/define.js +4 -5
  74. package/dataflow/environments/remove.d.ts +6 -0
  75. package/dataflow/environments/remove.js +29 -0
  76. package/dataflow/environments/resolve-by-name.d.ts +0 -36
  77. package/dataflow/environments/resolve-by-name.js +0 -240
  78. package/dataflow/eval/resolve/alias-tracking.d.ts +92 -0
  79. package/dataflow/eval/resolve/alias-tracking.js +352 -0
  80. package/dataflow/eval/resolve/resolve-argument.d.ts +8 -0
  81. package/dataflow/eval/resolve/resolve-argument.js +118 -0
  82. package/dataflow/eval/resolve/resolve.d.ts +37 -0
  83. package/dataflow/eval/resolve/resolve.js +95 -0
  84. package/dataflow/eval/values/general.d.ts +27 -0
  85. package/dataflow/eval/values/general.js +73 -0
  86. package/dataflow/eval/values/intervals/interval-constants.d.ts +4 -0
  87. package/dataflow/eval/values/intervals/interval-constants.js +27 -0
  88. package/dataflow/eval/values/logical/logical-constants.d.ts +7 -0
  89. package/dataflow/eval/values/logical/logical-constants.js +31 -0
  90. package/dataflow/eval/values/r-value.d.ts +58 -0
  91. package/dataflow/eval/values/r-value.js +90 -0
  92. package/dataflow/eval/values/scalar/scalar-consatnts.d.ts +15 -0
  93. package/dataflow/eval/values/scalar/scalar-consatnts.js +35 -0
  94. package/dataflow/eval/values/sets/set-constants.d.ts +7 -0
  95. package/dataflow/eval/values/sets/set-constants.js +34 -0
  96. package/dataflow/eval/values/string/string-constants.d.ts +8 -0
  97. package/dataflow/eval/values/string/string-constants.js +45 -0
  98. package/dataflow/eval/values/vectors/vector-constants.d.ts +14 -0
  99. package/dataflow/eval/values/vectors/vector-constants.js +35 -0
  100. package/dataflow/extractor.d.ts +2 -1
  101. package/dataflow/extractor.js +2 -1
  102. package/dataflow/graph/unknown-replacement.d.ts +11 -0
  103. package/dataflow/graph/unknown-replacement.js +12 -0
  104. package/dataflow/graph/unknown-side-effect.d.ts +7 -0
  105. package/dataflow/graph/unknown-side-effect.js +13 -0
  106. package/dataflow/internal/process/functions/call/built-in/built-in-access.js +5 -6
  107. package/dataflow/internal/process/functions/call/built-in/built-in-apply.js +8 -5
  108. package/dataflow/internal/process/functions/call/built-in/built-in-assignment.d.ts +4 -2
  109. package/dataflow/internal/process/functions/call/built-in/built-in-assignment.js +15 -13
  110. package/dataflow/internal/process/functions/call/built-in/built-in-eval.js +20 -18
  111. package/dataflow/internal/process/functions/call/built-in/built-in-expression-list.js +7 -2
  112. package/dataflow/internal/process/functions/call/built-in/built-in-for-loop.js +2 -3
  113. package/dataflow/internal/process/functions/call/built-in/built-in-if-then-else.js +5 -4
  114. package/dataflow/internal/process/functions/call/built-in/built-in-list.js +2 -2
  115. package/dataflow/internal/process/functions/call/built-in/built-in-replacement.js +11 -5
  116. package/dataflow/internal/process/functions/call/built-in/built-in-source.d.ts +5 -3
  117. package/dataflow/internal/process/functions/call/built-in/built-in-source.js +26 -29
  118. package/dataflow/internal/process/functions/call/built-in/built-in-vector.js +2 -2
  119. package/dataflow/internal/process/functions/call/built-in/built-in-while-loop.js +23 -0
  120. package/dataflow/internal/process/functions/call/common.js +1 -1
  121. package/dataflow/internal/process/functions/call/known-call-handling.js +2 -1
  122. package/dataflow/internal/process/functions/process-parameter.js +1 -1
  123. package/dataflow/origin/dfg-get-symbol-refs.d.ts +21 -0
  124. package/dataflow/origin/dfg-get-symbol-refs.js +50 -0
  125. package/dataflow/processor.d.ts +5 -0
  126. package/documentation/doc-util/doc-cfg.js +4 -3
  127. package/documentation/doc-util/doc-code.d.ts +1 -1
  128. package/documentation/doc-util/doc-dfg.js +3 -2
  129. package/documentation/doc-util/doc-functions.d.ts +24 -0
  130. package/documentation/doc-util/doc-functions.js +65 -0
  131. package/documentation/doc-util/doc-normalized-ast.js +3 -2
  132. package/documentation/doc-util/doc-print.d.ts +5 -0
  133. package/documentation/doc-util/doc-print.js +36 -0
  134. package/documentation/doc-util/doc-query.d.ts +6 -3
  135. package/documentation/doc-util/doc-query.js +6 -3
  136. package/documentation/doc-util/doc-repl.js +2 -1
  137. package/documentation/doc-util/doc-search.js +3 -2
  138. package/documentation/doc-util/doc-types.d.ts +28 -6
  139. package/documentation/doc-util/doc-types.js +89 -45
  140. package/documentation/print-cfg-wiki.js +10 -11
  141. package/documentation/print-core-wiki.js +5 -5
  142. package/documentation/print-dataflow-graph-wiki.js +14 -13
  143. package/documentation/print-engines-wiki.js +2 -3
  144. package/documentation/print-faq-wiki.js +8 -2
  145. package/documentation/print-interface-wiki.js +1 -2
  146. package/documentation/print-linter-issue.d.ts +1 -0
  147. package/documentation/print-linter-issue.js +71 -0
  148. package/documentation/print-linter-wiki.js +219 -34
  149. package/documentation/print-linting-and-testing-wiki.js +2 -4
  150. package/documentation/print-normalized-ast-wiki.js +3 -3
  151. package/documentation/print-query-wiki.js +81 -2
  152. package/documentation/print-readme.js +24 -1
  153. package/documentation/print-search-wiki.js +1 -2
  154. package/linter/linter-executor.d.ts +3 -1
  155. package/linter/linter-executor.js +3 -2
  156. package/linter/linter-format.d.ts +67 -7
  157. package/linter/linter-format.js +12 -1
  158. package/linter/linter-rules.d.ts +155 -16
  159. package/linter/linter-rules.js +12 -4
  160. package/linter/linter-tags.d.ts +80 -0
  161. package/linter/linter-tags.js +85 -0
  162. package/linter/rules/absolute-path.d.ts +71 -0
  163. package/linter/rules/absolute-path.js +177 -0
  164. package/linter/rules/deprecated-functions.d.ts +43 -0
  165. package/linter/rules/deprecated-functions.js +58 -0
  166. package/linter/rules/{2-file-path-validity.d.ts → file-path-validity.d.ts} +16 -6
  167. package/linter/rules/{2-file-path-validity.js → file-path-validity.js} +21 -13
  168. package/linter/rules/naming-convention.d.ts +71 -0
  169. package/linter/rules/naming-convention.js +164 -0
  170. package/linter/rules/seeded-randomness.d.ts +65 -0
  171. package/linter/rules/seeded-randomness.js +122 -0
  172. package/linter/rules/unused-definition.d.ts +41 -0
  173. package/linter/rules/unused-definition.js +105 -0
  174. package/package.json +4 -1
  175. package/queries/base-query-format.d.ts +2 -0
  176. package/queries/catalog/call-context-query/call-context-query-executor.d.ts +1 -1
  177. package/queries/catalog/call-context-query/call-context-query-executor.js +2 -2
  178. package/queries/catalog/cluster-query/cluster-query-format.d.ts +1 -1
  179. package/queries/catalog/config-query/config-query-executor.d.ts +1 -1
  180. package/queries/catalog/config-query/config-query-executor.js +2 -3
  181. package/queries/catalog/control-flow-query/control-flow-query-executor.d.ts +3 -0
  182. package/queries/catalog/control-flow-query/control-flow-query-executor.js +20 -0
  183. package/queries/catalog/control-flow-query/control-flow-query-format.d.ts +81 -0
  184. package/queries/catalog/control-flow-query/control-flow-query-format.js +34 -0
  185. package/queries/catalog/dataflow-lens-query/dataflow-lens-query-format.d.ts +1 -1
  186. package/queries/catalog/dataflow-query/dataflow-query-format.d.ts +1 -1
  187. package/queries/catalog/dependencies-query/dependencies-query-executor.js +4 -115
  188. package/queries/catalog/dependencies-query/dependencies-query-format.d.ts +1 -1
  189. package/queries/catalog/happens-before-query/happens-before-query-format.d.ts +1 -1
  190. package/queries/catalog/id-map-query/id-map-query-format.d.ts +1 -1
  191. package/queries/catalog/lineage-query/lineage-query-format.d.ts +1 -1
  192. package/queries/catalog/linter-query/linter-query-executor.d.ts +1 -1
  193. package/queries/catalog/linter-query/linter-query-executor.js +2 -2
  194. package/queries/catalog/linter-query/linter-query-format.d.ts +1 -1
  195. package/queries/catalog/linter-query/linter-query-format.js +17 -12
  196. package/queries/catalog/normalized-ast-query/normalized-ast-query-format.d.ts +1 -1
  197. package/queries/catalog/origin-query/origin-query-format.d.ts +1 -1
  198. package/queries/catalog/project-query/project-query-format.d.ts +1 -1
  199. package/queries/catalog/resolve-value-query/resolve-value-query-executor.d.ts +1 -1
  200. package/queries/catalog/resolve-value-query/resolve-value-query-executor.js +4 -4
  201. package/queries/catalog/resolve-value-query/resolve-value-query-format.d.ts +3 -2
  202. package/queries/catalog/resolve-value-query/resolve-value-query-format.js +2 -22
  203. package/queries/catalog/search-query/search-query-executor.d.ts +1 -1
  204. package/queries/catalog/search-query/search-query-executor.js +2 -2
  205. package/queries/catalog/search-query/search-query-format.d.ts +1 -1
  206. package/queries/catalog/static-slice-query/static-slice-query-executor.d.ts +1 -1
  207. package/queries/catalog/static-slice-query/static-slice-query-executor.js +2 -2
  208. package/queries/catalog/static-slice-query/static-slice-query-format.d.ts +1 -1
  209. package/queries/query.d.ts +75 -15
  210. package/queries/query.js +2 -0
  211. package/r-bridge/lang-4.x/ast/parser/json/parser.d.ts +2 -1
  212. package/r-bridge/lang-4.x/ast/parser/json/parser.js +4 -2
  213. package/r-bridge/lang-4.x/convert-values.js +2 -1
  214. package/r-bridge/lang-4.x/tree-sitter/tree-sitter-executor.d.ts +3 -1
  215. package/r-bridge/lang-4.x/tree-sitter/tree-sitter-executor.js +4 -4
  216. package/r-bridge/lang-4.x/tree-sitter/tree-sitter-normalize.d.ts +1 -1
  217. package/r-bridge/lang-4.x/tree-sitter/tree-sitter-normalize.js +18 -9
  218. package/r-bridge/shell.d.ts +3 -2
  219. package/r-bridge/shell.js +4 -5
  220. package/search/flowr-search-builder.d.ts +6 -2
  221. package/search/flowr-search-builder.js +7 -0
  222. package/search/flowr-search-filters.d.ts +32 -8
  223. package/search/flowr-search-filters.js +42 -15
  224. package/search/flowr-search.d.ts +4 -0
  225. package/search/search-executor/search-enrichers.d.ts +7 -3
  226. package/search/search-executor/search-enrichers.js +32 -20
  227. package/search/search-executor/search-generators.js +1 -1
  228. package/search/search-executor/search-transformer.d.ts +2 -0
  229. package/search/search-executor/search-transformer.js +10 -1
  230. package/slicing/criterion/parse.d.ts +8 -0
  231. package/slicing/criterion/parse.js +20 -0
  232. package/slicing/static/static-slicer.d.ts +1 -1
  233. package/slicing/static/static-slicer.js +2 -3
  234. package/statistics/statistics.d.ts +3 -1
  235. package/statistics/statistics.js +5 -4
  236. package/util/containers.d.ts +12 -9
  237. package/util/containers.js +12 -9
  238. package/util/objects.d.ts +5 -4
  239. package/util/range.d.ts +5 -1
  240. package/util/range.js +11 -3
  241. package/util/text/strings.d.ts +6 -0
  242. package/util/text/strings.js +35 -0
  243. package/util/version.js +1 -1
  244. package/linter/rules/1-deprecated-functions.d.ts +0 -34
  245. package/linter/rules/1-deprecated-functions.js +0 -54
@@ -1,22 +1,41 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.FlowrFilterCombinator = exports.FlowrFilters = exports.ValidFlowrFiltersReverse = exports.ValidFlowrFilters = exports.FlowrFilter = void 0;
4
+ exports.testFunctionsIgnoringPackage = testFunctionsIgnoringPackage;
4
5
  exports.binaryTreeToString = binaryTreeToString;
5
6
  exports.isBinaryTree = isBinaryTree;
6
7
  exports.evalFilter = evalFilter;
7
8
  const type_1 = require("../r-bridge/lang-4.x/ast/model/type");
8
9
  const vertex_1 = require("../dataflow/graph/vertex");
10
+ const search_enrichers_1 = require("./search-executor/search-enrichers");
9
11
  var FlowrFilter;
10
12
  (function (FlowrFilter) {
13
+ /**
14
+ * Drops search elements that represent empty arguments. Specifically, all nodes that are arguments and have an undefined name are skipped.
15
+ * This filter does not accept any arguments.
16
+ */
11
17
  FlowrFilter["DropEmptyArguments"] = "drop-empty-arguments";
18
+ /**
19
+ * Only returns search elements whose enrichments' JSON representations match a given test regular expression.
20
+ * This filter accepts {@link MatchesEnrichmentArgs}, which includes the enrichment to match for, as well as the regular expression to test the enrichment's (non-pretty-printed) JSON representation for.
21
+ * To test for included function names in an enrichment like {@link Enrichment.CallTargets}, the helper function {@link testFunctionsIgnoringPackage} can be used.
22
+ */
23
+ FlowrFilter["MatchesEnrichment"] = "matches-enrichment";
12
24
  })(FlowrFilter || (exports.FlowrFilter = FlowrFilter = {}));
13
25
  exports.ValidFlowrFilters = new Set(Object.values(FlowrFilter));
14
26
  exports.ValidFlowrFiltersReverse = Object.fromEntries(Object.entries(FlowrFilter).map(([k, v]) => [v, k]));
15
27
  exports.FlowrFilters = {
16
- [FlowrFilter.DropEmptyArguments]: (n) => {
17
- return n.type !== type_1.RType.Argument || n.name !== undefined;
18
- }
28
+ [FlowrFilter.DropEmptyArguments]: ((e, _args) => {
29
+ return e.node.type !== type_1.RType.Argument || e.node.name !== undefined;
30
+ }),
31
+ [FlowrFilter.MatchesEnrichment]: ((e, args) => {
32
+ const content = JSON.stringify((0, search_enrichers_1.enrichmentContent)(e, args.enrichment));
33
+ return content !== undefined && args.test.test(content);
34
+ })
19
35
  };
36
+ function testFunctionsIgnoringPackage(functions) {
37
+ return new RegExp(`"(.+:::?)?(${functions.join('|')})"`);
38
+ }
20
39
  /**
21
40
  * @see {@link FlowrFilterCombinator.is}
22
41
  * @see {@link evalFilter}
@@ -28,8 +47,17 @@ class FlowrFilterCombinator {
28
47
  this.tree = this.unpack(init);
29
48
  }
30
49
  static is(value) {
31
- if (typeof value === 'object') {
32
- return new this(value);
50
+ if (typeof value === 'string' && exports.ValidFlowrFilters.has(value)) {
51
+ return new this({ type: 'special', value: value });
52
+ }
53
+ else if (typeof value === 'object') {
54
+ const name = value?.name;
55
+ if (name && exports.ValidFlowrFilters.has(name)) {
56
+ return new this({ type: 'special', value: value });
57
+ }
58
+ else {
59
+ return new this(value);
60
+ }
33
61
  }
34
62
  else if (type_1.ValidRTypes.has(value)) {
35
63
  return new this({ type: 'r-type', value: value });
@@ -37,9 +65,6 @@ class FlowrFilterCombinator {
37
65
  else if (vertex_1.ValidVertexTypes.has(value)) {
38
66
  return new this({ type: 'vertex-type', value: value });
39
67
  }
40
- else if (exports.ValidFlowrFilters.has(value)) {
41
- return new this({ type: 'special', value: value });
42
- }
43
68
  else {
44
69
  throw new Error(`Invalid filter value: ${value}`);
45
70
  }
@@ -97,7 +122,7 @@ const typeToSymbol = {
97
122
  };
98
123
  function treeToStringImpl(tree, depth) {
99
124
  if (tree.type === 'r-type' || tree.type === 'vertex-type' || tree.type === 'special') {
100
- return tree.value;
125
+ return typeof tree.value === 'string' ? tree.value : `${tree.value.name}@${JSON.stringify(tree.value.args)}`;
101
126
  }
102
127
  if (tree.type === 'not') {
103
128
  return `${typeToSymbol[tree.type]}${treeToStringImpl(tree.operand, depth)}`;
@@ -114,14 +139,16 @@ const evalVisit = {
114
139
  or: ({ left, right }, data) => evalTree(left, data) || evalTree(right, data),
115
140
  xor: ({ left, right }, data) => evalTree(left, data) !== evalTree(right, data),
116
141
  not: ({ operand }, data) => !evalTree(operand, data),
117
- 'r-type': ({ value }, { node }) => node.type === value,
118
- 'vertex-type': ({ value }, { dataflow: { graph }, node }) => graph.getVertex(node.info.id)?.tag === value,
119
- 'special': ({ value }, { node }) => {
120
- const getHandler = exports.FlowrFilters[value];
142
+ 'r-type': ({ value }, { element }) => element.node.type === value,
143
+ 'vertex-type': ({ value }, { dataflow: { graph }, element }) => graph.getVertex(element.node.info.id)?.tag === value,
144
+ 'special': ({ value }, { element }) => {
145
+ const name = typeof value === 'string' ? value : value.name;
146
+ const args = typeof value === 'string' ? undefined : value.args;
147
+ const getHandler = exports.FlowrFilters[name];
121
148
  if (getHandler) {
122
- return getHandler(node);
149
+ return getHandler(element, args);
123
150
  }
124
- throw new Error(`Special filter not implemented: ${value}`);
151
+ throw new Error(`Couldn't find special filter with name ${name}`);
125
152
  }
126
153
  };
127
154
  function evalTree(tree, data) {
@@ -5,6 +5,8 @@ import type { NodeId } from '../r-bridge/lang-4.x/ast/model/processing/node-id';
5
5
  import type { DataflowInformation } from '../dataflow/info';
6
6
  import type { BaseQueryResult } from '../queries/base-query-format';
7
7
  import type { Query } from '../queries/query';
8
+ import type { FlowrConfigOptions } from '../config';
9
+ import type { MarkOptional } from 'ts-essentials';
8
10
  /**
9
11
  * Yes, for now we do technically not need a wrapper around the RNode, but this allows us to attach caches etc.
10
12
  * just for the respective search.
@@ -16,6 +18,7 @@ export interface FlowrSearchElementFromQuery<Info> extends FlowrSearchElement<In
16
18
  readonly query: Query['type'];
17
19
  readonly queryResult: BaseQueryResult;
18
20
  }
21
+ export type FlowrSearchElementMaybeFromQuery<Info> = MarkOptional<FlowrSearchElementFromQuery<Info>, 'query' | 'queryResult'>;
19
22
  export interface FlowrSearchNodeBase<Type extends string, Name extends string, Args extends Record<string, unknown> | undefined> {
20
23
  readonly type: Type;
21
24
  readonly name: Name;
@@ -49,6 +52,7 @@ export interface FlowrSearchGetFilter extends Record<string, unknown> {
49
52
  type MinimumInputForFlowrSearch<P extends Pipeline> = PipelineStepOutputWithName<P, 'normalize'> extends NormalizedAst ? (PipelineStepOutputWithName<P, 'dataflow'> extends DataflowInformation ? PipelineOutput<P> & {
50
53
  normalize: NormalizedAst;
51
54
  dataflow: DataflowInformation;
55
+ config: FlowrConfigOptions;
52
56
  } : never) : never;
53
57
  /** we allow any pipeline, which provides us with a 'normalize' and 'dataflow' step */
54
58
  export type FlowrSearchInput<P extends Pipeline> = MinimumInputForFlowrSearch<P>;
@@ -17,7 +17,7 @@ export interface EnrichmentData<EnrichmentContent extends MergeableRecord, Enric
17
17
  /**
18
18
  * A function that is applied to each element of the search to enrich it with additional data.
19
19
  */
20
- readonly enrich: (e: FlowrSearchElement<ParentInformation>, data: FlowrSearchInput<Pipeline>, args: EnrichmentArguments | undefined) => EnrichmentContent;
20
+ readonly enrich: (e: FlowrSearchElement<ParentInformation>, data: FlowrSearchInput<Pipeline>, args: EnrichmentArguments | undefined, previousValue: EnrichmentContent | undefined) => EnrichmentContent;
21
21
  /**
22
22
  * The mapping function used by the {@link Mapper.Enrichment} mapper.
23
23
  */
@@ -52,14 +52,18 @@ export declare const Enrichments: {
52
52
  enrich: (e: FlowrSearchElement<ParentInformation>, data: import("../../core/steps/pipeline/pipeline").PipelineOutput<Pipeline<import("../../core/steps/pipeline-step").IPipelineStep<import("../../core/steps/pipeline-step").PipelineStepName, (...args: any[]) => any>>> & {
53
53
  normalize: import("../../r-bridge/lang-4.x/ast/model/processing/decorate").NormalizedAst;
54
54
  dataflow: import("../../dataflow/info").DataflowInformation;
55
- }) => CallTargetsContent;
55
+ config: import("../../config").FlowrConfigOptions;
56
+ }, args: {
57
+ onlyBuiltin?: boolean;
58
+ } | undefined, prev: CallTargetsContent | undefined) => CallTargetsContent;
56
59
  mapper: ({ targets }: CallTargetsContent) => FlowrSearchElement<ParentInformation>[];
57
60
  };
58
61
  readonly "last-call": {
59
62
  enrich: (e: FlowrSearchElement<ParentInformation>, data: import("../../core/steps/pipeline/pipeline").PipelineOutput<Pipeline<import("../../core/steps/pipeline-step").IPipelineStep<import("../../core/steps/pipeline-step").PipelineStepName, (...args: any[]) => any>>> & {
60
63
  normalize: import("../../r-bridge/lang-4.x/ast/model/processing/decorate").NormalizedAst;
61
64
  dataflow: import("../../dataflow/info").DataflowInformation;
62
- }, args: Omit<LinkToLastCall<string | RegExp>, "type">[] | undefined) => LastCallContent;
65
+ config: import("../../config").FlowrConfigOptions;
66
+ }, args: Omit<LinkToLastCall<string | RegExp>, "type">[] | undefined, prev: LastCallContent | undefined) => LastCallContent;
63
67
  mapper: ({ linkedIds }: LastCallContent) => FlowrSearchElement<ParentInformation>[];
64
68
  };
65
69
  };
@@ -4,11 +4,11 @@ exports.Enrichments = exports.Enrichment = void 0;
4
4
  exports.enrichmentContent = enrichmentContent;
5
5
  exports.enrich = enrich;
6
6
  const vertex_1 = require("../../dataflow/graph/vertex");
7
- const log_1 = require("../../util/log");
8
7
  const identify_link_to_last_call_relation_1 = require("../../queries/catalog/call-context-query/identify-link-to-last-call-relation");
9
8
  const assert_1 = require("../../util/assert");
10
9
  const extract_cfg_1 = require("../../control-flow/extract-cfg");
11
10
  const dfg_get_origin_1 = require("../../dataflow/origin/dfg-get-origin");
11
+ const node_id_1 = require("../../r-bridge/lang-4.x/ast/model/processing/node-id");
12
12
  /**
13
13
  * An enumeration that stores the names of the available enrichments that can be applied to a set of search elements.
14
14
  * See {@link FlowrSearchBuilder.with} for more information on how to apply enrichments.
@@ -24,29 +24,40 @@ var Enrichment;
24
24
  */
25
25
  exports.Enrichments = {
26
26
  [Enrichment.CallTargets]: {
27
- enrich: (e, data) => {
27
+ enrich: (e, data, args, prev) => {
28
28
  // we don't resolve aliases here yet!
29
29
  const content = { targets: [] };
30
30
  const callVertex = data.dataflow.graph.getVertex(e.node.info.id);
31
31
  if (callVertex?.tag === vertex_1.VertexType.FunctionCall) {
32
32
  const origins = (0, dfg_get_origin_1.getOriginInDfg)(data.dataflow.graph, callVertex.id);
33
33
  if (!origins || origins.length === 0) {
34
- log_1.log.warn(`No origin found for call vertex ${callVertex.id}, cannot resolve call targets.`);
35
- return content;
34
+ content.targets = [(0, node_id_1.recoverName)(callVertex.id, data.normalize.idMap)];
36
35
  }
37
- // find call targets in user code (which have ids!)
38
- content.targets = content.targets.concat(origins.map(o => {
39
- switch (o.type) {
40
- case 2 /* OriginType.FunctionCallOrigin */:
41
- return {
42
- node: data.normalize.idMap.get(o.id),
43
- };
44
- case 3 /* OriginType.BuiltInFunctionOrigin */:
45
- return o.fn.name;
46
- default:
47
- return undefined;
36
+ else {
37
+ // find call targets in user code (which have ids!)
38
+ content.targets = content.targets.concat(origins.map(o => {
39
+ switch (o.type) {
40
+ case 2 /* OriginType.FunctionCallOrigin */:
41
+ return {
42
+ node: data.normalize.idMap.get(o.id),
43
+ };
44
+ case 3 /* OriginType.BuiltInFunctionOrigin */:
45
+ return o.fn.name;
46
+ default:
47
+ return undefined;
48
+ }
49
+ }).filter(assert_1.isNotUndefined));
50
+ if (content.targets.length === 0) {
51
+ content.targets = [(0, node_id_1.recoverName)(callVertex.id, data.normalize.idMap)];
48
52
  }
49
- }).filter(assert_1.isNotUndefined));
53
+ }
54
+ }
55
+ // if there is a call target that is not built-in (ie a custom function), we don't want to include it here
56
+ if (args?.onlyBuiltin && content.targets.some(t => typeof t !== 'string')) {
57
+ content.targets = [];
58
+ }
59
+ if (prev) {
60
+ content.targets.push(...prev.targets);
50
61
  }
51
62
  return content;
52
63
  },
@@ -54,9 +65,9 @@ exports.Enrichments = {
54
65
  mapper: ({ targets }) => targets.map(t => t).filter(t => t.node !== undefined)
55
66
  },
56
67
  [Enrichment.LastCall]: {
57
- enrich: (e, data, args) => {
68
+ enrich: (e, data, args, prev) => {
58
69
  (0, assert_1.guard)(args && args.length, `${Enrichment.LastCall} enrichment requires at least one argument`);
59
- const content = { linkedIds: [] };
70
+ const content = prev ?? { linkedIds: [] };
60
71
  const vertex = data.dataflow.graph.get(e.node.info.id);
61
72
  if (vertex !== undefined && vertex[0].tag === vertex_1.VertexType.FunctionCall) {
62
73
  const cfg = (0, extract_cfg_1.extractSimpleCfg)(data.normalize);
@@ -87,11 +98,12 @@ function enrichmentContent(e, enrichment) {
87
98
  }
88
99
  function enrich(e, data, enrichment, args) {
89
100
  const enrichmentData = exports.Enrichments[enrichment];
101
+ const prev = e?.enrichments;
90
102
  return {
91
103
  ...e,
92
104
  enrichments: {
93
- ...e?.enrichments ?? {},
94
- [enrichment]: enrichmentData.enrich(e, data, args)
105
+ ...prev ?? {},
106
+ [enrichment]: enrichmentData.enrich(e, data, args, prev?.[enrichment])
95
107
  }
96
108
  };
97
109
  }
@@ -56,7 +56,7 @@ function generateFrom(data, args) {
56
56
  }
57
57
  function generateFromQuery(data, args) {
58
58
  const nodes = new Set();
59
- const result = (0, query_1.executeQueries)({ ast: data.normalize, dataflow: data.dataflow }, args.from);
59
+ const result = (0, query_1.executeQueries)({ ast: data.normalize, dataflow: data.dataflow, config: data.config }, args.from);
60
60
  for (const [query, content] of Object.entries(result)) {
61
61
  if (query === '.meta') {
62
62
  continue;
@@ -29,6 +29,7 @@ export declare const transformers: {
29
29
  readonly skip: typeof getSkip;
30
30
  readonly filter: typeof getFilter;
31
31
  readonly merge: typeof getMerge;
32
+ readonly unique: typeof getUnique;
32
33
  readonly select: typeof getSelect;
33
34
  readonly with: typeof getWith;
34
35
  readonly map: typeof getMap;
@@ -66,4 +67,5 @@ declare function getMerge<Elements extends FlowrSearchElement<ParentInformation>
66
67
  search: unknown[];
67
68
  generator: FlowrSearchGeneratorNode;
68
69
  }): FlowrSearchElements<ParentInformation, FlowrSearchElement<ParentInformation>[]>;
70
+ declare function getUnique<Elements extends FlowrSearchElement<ParentInformation>[], FSE extends FlowrSearchElements<ParentInformation, Elements>>(data: FlowrSearchInput<Pipeline>, elements: FSE): CascadeEmpty<Elements, Elements>;
69
71
  export {};
@@ -19,6 +19,7 @@ exports.transformers = {
19
19
  skip: getSkip,
20
20
  filter: getFilter,
21
21
  merge: getMerge,
22
+ unique: getUnique,
22
23
  select: getSelect,
23
24
  with: getWith,
24
25
  map: getMap
@@ -92,7 +93,7 @@ function getSkip(data, elements, { count }) {
92
93
  return elements.mutate(e => sortFully(e).slice(count));
93
94
  }
94
95
  function getFilter(data, elements, { filter }) {
95
- return elements.mutate(e => e.filter(({ node }) => (0, flowr_search_filters_1.evalFilter)(filter, { node, normalize: data.normalize, dataflow: data.dataflow })));
96
+ return elements.mutate(e => e.filter(e => (0, flowr_search_filters_1.evalFilter)(filter, { element: e, normalize: data.normalize, dataflow: data.dataflow })));
96
97
  }
97
98
  function getWith(data, elements, { info, args }) {
98
99
  return elements.mutate(elements => elements.map(e => (0, search_enrichers_1.enrich)(e, data, info, args)));
@@ -106,4 +107,12 @@ data, elements, other) {
106
107
  const resultOther = (0, flowr_search_executor_1.runSearch)(other, data);
107
108
  return elements.addAll(resultOther);
108
109
  }
110
+ function getUnique(data, elements) {
111
+ return elements.mutate(e => e.reduce((acc, cur) => {
112
+ if (!acc.some(el => el.node.id === cur.node.id)) {
113
+ acc.push(cur);
114
+ }
115
+ return acc;
116
+ }, []));
117
+ }
109
118
  //# sourceMappingURL=search-transformer.js.map
@@ -11,8 +11,16 @@ export declare class CriteriaParseError extends Error {
11
11
  }
12
12
  /**
13
13
  * Takes a criterion in the form of `line:column` or `line@variable-name` and returns the corresponding node id
14
+ *
15
+ * @see {@link tryResolveSliceCriterionToId} for a version that does not throw an error
14
16
  */
15
17
  export declare function slicingCriterionToId(criterion: SingleSlicingCriterion, idMap: AstIdMap): NodeId;
18
+ /**
19
+ * Tries to resolve a slicing criterion to an id, but does not throw an error if it fails.
20
+ *
21
+ * @see {@link slicingCriterionToId} for the version that throws an error
22
+ */
23
+ export declare function tryResolveSliceCriterionToId(criterion: string | NodeId, idMap: AstIdMap): NodeId | undefined;
16
24
  export interface DecodedCriterion {
17
25
  criterion: SingleSlicingCriterion;
18
26
  id: NodeId;
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.CriteriaParseError = void 0;
4
4
  exports.slicingCriterionToId = slicingCriterionToId;
5
+ exports.tryResolveSliceCriterionToId = tryResolveSliceCriterionToId;
5
6
  exports.convertAllSlicingCriteriaToIds = convertAllSlicingCriteriaToIds;
6
7
  const log_1 = require("../../util/log");
7
8
  const node_id_1 = require("../../r-bridge/lang-4.x/ast/model/processing/node-id");
@@ -19,6 +20,8 @@ class CriteriaParseError extends Error {
19
20
  exports.CriteriaParseError = CriteriaParseError;
20
21
  /**
21
22
  * Takes a criterion in the form of `line:column` or `line@variable-name` and returns the corresponding node id
23
+ *
24
+ * @see {@link tryResolveSliceCriterionToId} for a version that does not throw an error
22
25
  */
23
26
  function slicingCriterionToId(criterion, idMap) {
24
27
  let resolved;
@@ -38,6 +41,23 @@ function slicingCriterionToId(criterion, idMap) {
38
41
  }
39
42
  return resolved;
40
43
  }
44
+ /**
45
+ * Tries to resolve a slicing criterion to an id, but does not throw an error if it fails.
46
+ *
47
+ * @see {@link slicingCriterionToId} for the version that throws an error
48
+ */
49
+ function tryResolveSliceCriterionToId(criterion, idMap) {
50
+ try {
51
+ return slicingCriterionToId(criterion, idMap);
52
+ }
53
+ catch (e) {
54
+ if (e instanceof CriteriaParseError) {
55
+ (0, log_1.expensiveTrace)(static_slicer_1.slicerLogger, () => `could not resolve slicing criterion ${criterion}: ${e.message}`);
56
+ return undefined;
57
+ }
58
+ throw e; // rethrow other errors
59
+ }
60
+ }
41
61
  function locationToId(location, dataflowIdMap) {
42
62
  let candidate;
43
63
  for (const [id, nodeInfo] of dataflowIdMap.entries()) {
@@ -14,7 +14,7 @@ export declare const slicerLogger: import("tslog").Logger<import("tslog").ILogOb
14
14
  *
15
15
  * @param graph - The dataflow graph to conduct the slicing on.
16
16
  * @param ast - The normalized AST of the code (used to get static nesting information of the lexemes in case of control flow dependencies that may have no effect on the slicing scope).
17
- * @param criteria - The criterias to slice on.
17
+ * @param criteria - The criteria to slice on.
18
18
  * @param threshold - The maximum number of nodes to visit in the graph. If the threshold is reached, the slice will side with inclusion and drop its minimal guarantee. The limit ensures that the algorithm halts.
19
19
  * @param cache - A cache to store the results of the slice. If provided, the slice may use this cache to speed up the slicing process.
20
20
  */
@@ -12,7 +12,6 @@ const parse_1 = require("../criterion/parse");
12
12
  const environment_1 = require("../../dataflow/environments/environment");
13
13
  const vertex_1 = require("../../dataflow/graph/vertex");
14
14
  const edge_1 = require("../../dataflow/graph/edge");
15
- const config_1 = require("../../config");
16
15
  exports.slicerLogger = log_1.log.getSubLogger({ name: 'slicer' });
17
16
  /**
18
17
  * This returns the ids to include in the static backward slice, when slicing with the given seed id's (must be at least one).
@@ -21,11 +20,11 @@ exports.slicerLogger = log_1.log.getSubLogger({ name: 'slicer' });
21
20
  *
22
21
  * @param graph - The dataflow graph to conduct the slicing on.
23
22
  * @param ast - The normalized AST of the code (used to get static nesting information of the lexemes in case of control flow dependencies that may have no effect on the slicing scope).
24
- * @param criteria - The criterias to slice on.
23
+ * @param criteria - The criteria to slice on.
25
24
  * @param threshold - The maximum number of nodes to visit in the graph. If the threshold is reached, the slice will side with inclusion and drop its minimal guarantee. The limit ensures that the algorithm halts.
26
25
  * @param cache - A cache to store the results of the slice. If provided, the slice may use this cache to speed up the slicing process.
27
26
  */
28
- function staticSlicing(graph, { idMap }, criteria, threshold = (0, config_1.getConfig)().solver.slicer?.threshold ?? 75, cache) {
27
+ function staticSlicing(graph, { idMap }, criteria, threshold = 75, cache) {
29
28
  (0, assert_1.guard)(criteria.length > 0, 'must have at least one seed id to calculate slice');
30
29
  const decodedCriteria = (0, parse_1.convertAllSlicingCriteriaToIds)(criteria, idMap);
31
30
  (0, log_1.expensiveTrace)(exports.slicerLogger, () => `calculating slice for ${decodedCriteria.length} seed criteria: ${decodedCriteria.map(s => JSON.stringify(s)).join(', ')}`);
@@ -4,6 +4,7 @@ import type { PipelineOutput } from '../core/steps/pipeline/pipeline';
4
4
  import { DEFAULT_DATAFLOW_PIPELINE } from '../core/steps/pipeline/default-pipelines';
5
5
  import type { RShell } from '../r-bridge/shell';
6
6
  import type { FeatureSelection, FeatureStatistics } from './features/feature';
7
+ import type { FlowrConfigOptions } from '../config';
7
8
  /**
8
9
  * By default, {@link extractUsageStatistics} requires a generator, but sometimes you already know all the files
9
10
  * that you want to process. This function simply reps your requests as a generator.
@@ -14,13 +15,14 @@ type DataflowResult = PipelineOutput<typeof DEFAULT_DATAFLOW_PIPELINE>;
14
15
  * Extract all wanted statistic information from a set of requests using the presented R session.
15
16
  *
16
17
  * @param shell - The R session to use
18
+ * @param config - The flowr config
17
19
  * @param onRequest - A callback that is called at the beginning of each request, this may be used to debug the requests.
18
20
  * @param features - The features to extract (see {@link allFeatureNames}).
19
21
  * @param requests - The requests to extract the features from. May generate them on demand (e.g., by traversing a folder).
20
22
  * If your request is statically known, you can use {@link staticRequests} to create this generator.
21
23
  * @param rootPath - The root path to the project, this is used to relativize the file paths in the statistics.
22
24
  */
23
- export declare function extractUsageStatistics<T extends RParseRequestFromText | RParseRequestFromFile>(shell: RShell, onRequest: (request: T) => void, features: FeatureSelection, requests: AsyncGenerator<T>, rootPath?: string): Promise<{
25
+ export declare function extractUsageStatistics<T extends RParseRequestFromText | RParseRequestFromFile>(shell: RShell, config: FlowrConfigOptions, onRequest: (request: T) => void, features: FeatureSelection, requests: AsyncGenerator<T>, rootPath?: string): Promise<{
24
26
  features: FeatureStatistics;
25
27
  meta: MetaStatistics;
26
28
  outputs: Map<T, DataflowResult>;
@@ -30,13 +30,14 @@ function staticRequests(...requests) {
30
30
  * Extract all wanted statistic information from a set of requests using the presented R session.
31
31
  *
32
32
  * @param shell - The R session to use
33
+ * @param config - The flowr config
33
34
  * @param onRequest - A callback that is called at the beginning of each request, this may be used to debug the requests.
34
35
  * @param features - The features to extract (see {@link allFeatureNames}).
35
36
  * @param requests - The requests to extract the features from. May generate them on demand (e.g., by traversing a folder).
36
37
  * If your request is statically known, you can use {@link staticRequests} to create this generator.
37
38
  * @param rootPath - The root path to the project, this is used to relativize the file paths in the statistics.
38
39
  */
39
- async function extractUsageStatistics(shell, onRequest, features, requests, rootPath) {
40
+ async function extractUsageStatistics(shell, config, onRequest, features, requests, rootPath) {
40
41
  let result = initializeFeatureStatistics();
41
42
  const meta = (0, meta_statistics_1.initialMetaStatistics)();
42
43
  const outputs = new Map();
@@ -46,7 +47,7 @@ async function extractUsageStatistics(shell, onRequest, features, requests, root
46
47
  const suffix = request.request === 'file' ? request.content.replace(new RegExp('^' + (rootPath ?? '')), '') : undefined;
47
48
  try {
48
49
  let output;
49
- ({ stats: result, output } = await extractSingle(result, shell, request, features, suffix));
50
+ ({ stats: result, output } = await extractSingle(result, shell, request, features, suffix, config));
50
51
  outputs.set(request, output);
51
52
  processMetaOnSuccessful(meta, request);
52
53
  meta.numberOfNormalizedNodes.push(output.normalize.idMap.size);
@@ -80,10 +81,10 @@ function processMetaOnSuccessful(meta, request) {
80
81
  }
81
82
  }
82
83
  const parser = new xmldom_1.DOMParser();
83
- async function extractSingle(result, shell, request, features, suffixFilePath) {
84
+ async function extractSingle(result, shell, request, features, suffixFilePath, config) {
84
85
  const slicerOutput = await new pipeline_executor_1.PipelineExecutor(default_pipelines_1.DEFAULT_DATAFLOW_PIPELINE, {
85
86
  request, parser: shell
86
- }).allRemainingSteps();
87
+ }, config).allRemainingSteps();
87
88
  // retrieve parsed xml through (legacy) xmlparsedata
88
89
  const suffix = request.request === 'file' ? ', encoding="utf-8"' : '';
89
90
  shell.sendCommands(`try(flowr_parsed<-parse(${request.request}=${JSON.stringify(request.content)},keep.source=TRUE${suffix}),silent=FALSE)`, 'try(flowr_output<-xmlparsedata::xml_parse_data(flowr_parsed,includeText=TRUE,pretty=FALSE),silent=FALSE)');
@@ -13,7 +13,7 @@ export declare function getAccessOperands<OtherInfo>(args: readonly RFunctionArg
13
13
  accessArg: RArgument<OtherInfo & ParentInformation> | undefined;
14
14
  };
15
15
  /**
16
- * Resolves the passed name in the passed environment and returns the indicesCollection of the resolved definitions.
16
+ * Resolves the passed name within the passed environment and returns the indicesCollection of the resolved definitions.
17
17
  *
18
18
  * @param name - Name to resolve
19
19
  * @param environment - Environment in which name is resolved
@@ -25,9 +25,10 @@ export declare function resolveIndicesByName(name: Identifier, environment: REnv
25
25
  *
26
26
  * If no indices could be found that match the `accessArg`, the original indices are returned as overapproximation.
27
27
  *
28
- * @param accessedArg - The argument to resolve
29
- * @param accessArg - The argument which is used to filter the indices
30
- * @param environment - The environment in which {@link accessedArg} is resolved
28
+ * @param accessedArg - The argument to resolve
29
+ * @param accessArg - The argument which is used to filter the indices
30
+ * @param environment - The environment in which {@link accessedArg} is resolved
31
+ * @param isIndexBasedAccess - Whether the access is index-based (e.g. `x[1]`) or name-based (e.g. `x$name`)
31
32
  * @returns The filtered {@link ContainerIndicesCollection} of the resolved {@link accessedArg}
32
33
  */
33
34
  export declare function resolveSingleIndex(accessedArg: {
@@ -38,8 +39,9 @@ export declare function resolveSingleIndex(accessedArg: {
38
39
  /**
39
40
  * Filters the single indices of the {@link indicesCollection} according to the lexeme of the {@link accessArg}.
40
41
  *
41
- * @param indicesCollection - The {@link ContainerIndicesCollection} to filter
42
- * @param accessArg - The argument which is used to filter {@link indicesCollection}
42
+ * @param indicesCollection - The {@link ContainerIndicesCollection} to filter
43
+ * @param accessArg - The argument which is used to filter {@link indicesCollection}
44
+ * @param isIndexBasedAccess - Whether the access is index-based (e.g. `x[1]`) or name-based (e.g. `x$name`)
43
45
  * @returns The filtered copy of {@link indicesCollection}
44
46
  */
45
47
  export declare function filterIndices(indicesCollection: ContainerIndicesCollection, accessArg: {
@@ -54,8 +56,9 @@ export declare function filterIndices(indicesCollection: ContainerIndicesCollect
54
56
  * ```
55
57
  * would result in a list with the index `credentials`, which has the subIndex `username`.
56
58
  *
57
- * @param accessedArg - The top level argument that is accessed
58
- * @param leafIndices - The index at the end of the nested access i.e. `c` in `a$b$c`.
59
+ * @param accessedArg - The top level argument that is accessed
60
+ * @param leafIndices - The index at the end of the nested access i.e. `c` in `a$b$c`.
61
+ * @param constructIdentifier - A function that constructs the identifier for the index from the argument
59
62
  * @returns The constructed nested access
60
63
  */
61
64
  export declare function constructNestedAccess<OtherInfo>(accessedArg: RAccess<OtherInfo & ParentInformation>, leafIndices: ContainerIndices, constructIdentifier: (arg: RArgument<OtherInfo & ParentInformation>) => IndexIdentifier): ContainerIndices[];
@@ -63,6 +66,6 @@ export declare function constructNestedAccess<OtherInfo>(accessedArg: RAccess<Ot
63
66
  * Adds the passed list of {@link leafSubIndices} to the leaf (sub-)indices of {@link indicesCollection}.
64
67
  *
65
68
  * @param indicesCollection - Indices where to add the sub indices.
66
- * @param leafSubIndices - Indices that are added to the leaf indices.
69
+ * @param leafSubIndices - Indices that are added to the leaf indices.
67
70
  */
68
71
  export declare function addSubIndicesToLeafIndices(indicesCollection: ContainerIndices[], leafSubIndices: ContainerIndices[]): ContainerIndices[];
@@ -20,7 +20,7 @@ function getAccessOperands(args) {
20
20
  return { accessedArg, accessArg };
21
21
  }
22
22
  /**
23
- * Resolves the passed name in the passed environment and returns the indicesCollection of the resolved definitions.
23
+ * Resolves the passed name within the passed environment and returns the indicesCollection of the resolved definitions.
24
24
  *
25
25
  * @param name - Name to resolve
26
26
  * @param environment - Environment in which name is resolved
@@ -35,9 +35,10 @@ function resolveIndicesByName(name, environment) {
35
35
  *
36
36
  * If no indices could be found that match the `accessArg`, the original indices are returned as overapproximation.
37
37
  *
38
- * @param accessedArg - The argument to resolve
39
- * @param accessArg - The argument which is used to filter the indices
40
- * @param environment - The environment in which {@link accessedArg} is resolved
38
+ * @param accessedArg - The argument to resolve
39
+ * @param accessArg - The argument which is used to filter the indices
40
+ * @param environment - The environment in which {@link accessedArg} is resolved
41
+ * @param isIndexBasedAccess - Whether the access is index-based (e.g. `x[1]`) or name-based (e.g. `x$name`)
41
42
  * @returns The filtered {@link ContainerIndicesCollection} of the resolved {@link accessedArg}
42
43
  */
43
44
  function resolveSingleIndex(accessedArg, accessArg, environment, isIndexBasedAccess) {
@@ -55,8 +56,9 @@ function resolveSingleIndex(accessedArg, accessArg, environment, isIndexBasedAcc
55
56
  /**
56
57
  * Filters the single indices of the {@link indicesCollection} according to the lexeme of the {@link accessArg}.
57
58
  *
58
- * @param indicesCollection - The {@link ContainerIndicesCollection} to filter
59
- * @param accessArg - The argument which is used to filter {@link indicesCollection}
59
+ * @param indicesCollection - The {@link ContainerIndicesCollection} to filter
60
+ * @param accessArg - The argument which is used to filter {@link indicesCollection}
61
+ * @param isIndexBasedAccess - Whether the access is index-based (e.g. `x[1]`) or name-based (e.g. `x$name`)
60
62
  * @returns The filtered copy of {@link indicesCollection}
61
63
  */
62
64
  function filterIndices(indicesCollection, accessArg, isIndexBasedAccess) {
@@ -83,8 +85,9 @@ function filterIndices(indicesCollection, accessArg, isIndexBasedAccess) {
83
85
  * ```
84
86
  * would result in a list with the index `credentials`, which has the subIndex `username`.
85
87
  *
86
- * @param accessedArg - The top level argument that is accessed
87
- * @param leafIndices - The index at the end of the nested access i.e. `c` in `a$b$c`.
88
+ * @param accessedArg - The top level argument that is accessed
89
+ * @param leafIndices - The index at the end of the nested access i.e. `c` in `a$b$c`.
90
+ * @param constructIdentifier - A function that constructs the identifier for the index from the argument
88
91
  * @returns The constructed nested access
89
92
  */
90
93
  function constructNestedAccess(accessedArg, leafIndices, constructIdentifier) {
@@ -116,7 +119,7 @@ function constructNestedAccess(accessedArg, leafIndices, constructIdentifier) {
116
119
  * Adds the passed list of {@link leafSubIndices} to the leaf (sub-)indices of {@link indicesCollection}.
117
120
  *
118
121
  * @param indicesCollection - Indices where to add the sub indices.
119
- * @param leafSubIndices - Indices that are added to the leaf indices.
122
+ * @param leafSubIndices - Indices that are added to the leaf indices.
120
123
  */
121
124
  function addSubIndicesToLeafIndices(indicesCollection, leafSubIndices) {
122
125
  const result = [];
package/util/objects.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { DeepPartial, DeepRequired } from 'ts-essentials';
1
+ import type { DeepPartial, DeepReadonly, DeepRequired } from 'ts-essentials';
2
2
  /**
3
3
  * checks if `item` is an object (it may be an array, ...)
4
4
  */
@@ -6,13 +6,14 @@ export declare function isObjectOrArray(item: unknown): boolean;
6
6
  export type MergeableRecord = Record<string, unknown>;
7
7
  export type MergeableArray = unknown[];
8
8
  export type Mergeable = MergeableRecord | MergeableArray;
9
+ type OrReadonly<T> = T | Readonly<T> | DeepReadonly<T>;
9
10
  /**
10
11
  * Given two objects deeply merges them, if an object is an array it will merge the array values!
11
12
  * Guarantees some type safety by requiring objects to merge to be from the same type (allows undefined)
12
13
  */
13
- export declare function deepMergeObject<T extends Mergeable>(base: Required<T>, addon?: T | DeepPartial<T> | Partial<T>): Required<T>;
14
- export declare function deepMergeObject<T extends Mergeable>(base: DeepRequired<T>, addon?: T | DeepPartial<T> | Partial<T>): DeepRequired<T>;
15
- export declare function deepMergeObject<T extends Mergeable>(base: T, addon?: DeepPartial<T> | Partial<T>): T;
14
+ export declare function deepMergeObject<T extends Mergeable>(base: Required<OrReadonly<T>>, addon?: T | DeepPartial<T> | Partial<T>): Required<T>;
15
+ export declare function deepMergeObject<T extends Mergeable>(base: DeepRequired<OrReadonly<T>>, addon?: T | DeepPartial<T> | Partial<T>): DeepRequired<T>;
16
+ export declare function deepMergeObject<T extends Mergeable>(base: OrReadonly<T>, addon?: DeepPartial<T> | Partial<T>): T;
16
17
  export declare function deepMergeObject(base: Mergeable, addon: Mergeable): Mergeable;
17
18
  export declare function deepMergeObject(base?: Mergeable, addon?: Mergeable): Mergeable | undefined;
18
19
  type Defined<T> = Exclude<T, undefined>;
package/util/range.d.ts CHANGED
@@ -45,7 +45,7 @@ export declare function getRangeEnd(p: SourceRange | undefined): SourcePosition
45
45
  * @param ec - end column
46
46
  */
47
47
  export declare function rangeFrom(sl: number | string, sc: number | string, el: number | string, ec: number | string): SourceRange;
48
- export declare function mergeRanges(...rs: SourceRange[]): SourceRange;
48
+ export declare function mergeRanges(...rs: (SourceRange | undefined)[]): SourceRange;
49
49
  /**
50
50
  * @returns true iff `r1` starts and ends before `r2` starts (i.e., if `r1` and `r2` do not overlap and `r1` comes before `r2`
51
51
  */
@@ -64,3 +64,7 @@ export declare function addRanges([r1sl, r1sc, r1el, r1ec]: SourceRange, [r2sl,
64
64
  * @returns a positive number if `r1` comes after `r2`, a negative number if `r1` comes before `r2`, and `0` if they are equal
65
65
  */
66
66
  export declare function rangeCompare([r1sl, r1sc, ,]: SourceRange, [r2sl, r2sc, ,]: SourceRange): number;
67
+ /**
68
+ * Checks if the first range is a subset of the second range.
69
+ */
70
+ export declare function rangeIsSubsetOf([r1sl, r1sc, r1el, r1ec]: SourceRange, [r2sl, r2sc, r2el, r2ec]: SourceRange): boolean;