@eagleoutice/flowr 2.2.15 → 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 (212) 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 +2 -2
  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 +4 -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 +26 -42
  39. package/control-flow/cfg-dead-code.js +45 -2
  40. package/control-flow/cfg-simplification.d.ts +2 -0
  41. package/control-flow/control-flow-graph.d.ts +1 -0
  42. package/control-flow/control-flow-graph.js +4 -0
  43. package/control-flow/dfg-cfg-guided-visitor.d.ts +5 -3
  44. package/control-flow/dfg-cfg-guided-visitor.js +15 -4
  45. package/control-flow/extract-cfg.d.ts +4 -2
  46. package/control-flow/extract-cfg.js +4 -3
  47. package/control-flow/semantic-cfg-guided-visitor.d.ts +19 -1
  48. package/control-flow/semantic-cfg-guided-visitor.js +23 -3
  49. package/core/pipeline-executor.d.ts +4 -1
  50. package/core/pipeline-executor.js +6 -5
  51. package/core/steps/all/core/10-normalize.d.ts +2 -0
  52. package/core/steps/all/core/10-normalize.js +1 -1
  53. package/core/steps/all/core/11-normalize-tree-sitter.d.ts +2 -1
  54. package/core/steps/all/core/11-normalize-tree-sitter.js +2 -2
  55. package/core/steps/all/core/20-dataflow.d.ts +2 -1
  56. package/core/steps/all/core/20-dataflow.js +2 -2
  57. package/core/steps/all/static-slicing/00-slice.d.ts +2 -1
  58. package/core/steps/all/static-slicing/00-slice.js +2 -2
  59. package/core/steps/pipeline/default-pipelines.d.ts +32 -31
  60. package/core/steps/pipeline/default-pipelines.js +8 -8
  61. package/core/steps/pipeline-step.d.ts +2 -1
  62. package/dataflow/environments/built-in-config.d.ts +3 -3
  63. package/dataflow/environments/built-in.d.ts +7 -1
  64. package/dataflow/environments/built-in.js +2 -2
  65. package/dataflow/environments/default-builtin-config.js +4 -2
  66. package/dataflow/environments/define.d.ts +2 -1
  67. package/dataflow/environments/define.js +4 -5
  68. package/dataflow/environments/remove.d.ts +6 -0
  69. package/dataflow/environments/remove.js +29 -0
  70. package/dataflow/eval/resolve/alias-tracking.d.ts +7 -2
  71. package/dataflow/eval/resolve/alias-tracking.js +9 -6
  72. package/dataflow/eval/resolve/resolve-argument.d.ts +8 -0
  73. package/dataflow/eval/resolve/resolve-argument.js +118 -0
  74. package/dataflow/eval/resolve/resolve.d.ts +18 -15
  75. package/dataflow/eval/resolve/resolve.js +20 -18
  76. package/dataflow/eval/values/string/string-constants.d.ts +1 -1
  77. package/dataflow/eval/values/string/string-constants.js +7 -2
  78. package/dataflow/extractor.d.ts +2 -1
  79. package/dataflow/extractor.js +2 -1
  80. package/dataflow/internal/process/functions/call/built-in/built-in-access.js +5 -6
  81. package/dataflow/internal/process/functions/call/built-in/built-in-apply.js +1 -1
  82. package/dataflow/internal/process/functions/call/built-in/built-in-assignment.d.ts +4 -2
  83. package/dataflow/internal/process/functions/call/built-in/built-in-assignment.js +11 -11
  84. package/dataflow/internal/process/functions/call/built-in/built-in-eval.js +10 -11
  85. package/dataflow/internal/process/functions/call/built-in/built-in-expression-list.js +7 -2
  86. package/dataflow/internal/process/functions/call/built-in/built-in-for-loop.js +2 -3
  87. package/dataflow/internal/process/functions/call/built-in/built-in-if-then-else.js +1 -1
  88. package/dataflow/internal/process/functions/call/built-in/built-in-list.js +2 -2
  89. package/dataflow/internal/process/functions/call/built-in/built-in-replacement.js +2 -3
  90. package/dataflow/internal/process/functions/call/built-in/built-in-source.d.ts +5 -3
  91. package/dataflow/internal/process/functions/call/built-in/built-in-source.js +15 -15
  92. package/dataflow/internal/process/functions/call/built-in/built-in-vector.js +2 -2
  93. package/dataflow/internal/process/functions/call/built-in/built-in-while-loop.js +1 -1
  94. package/dataflow/internal/process/functions/call/common.js +1 -1
  95. package/dataflow/internal/process/functions/process-parameter.js +1 -1
  96. package/dataflow/origin/dfg-get-symbol-refs.d.ts +21 -0
  97. package/dataflow/origin/dfg-get-symbol-refs.js +50 -0
  98. package/dataflow/processor.d.ts +5 -0
  99. package/documentation/doc-util/doc-cfg.js +4 -3
  100. package/documentation/doc-util/doc-code.d.ts +1 -1
  101. package/documentation/doc-util/doc-dfg.js +3 -2
  102. package/documentation/doc-util/doc-functions.d.ts +24 -0
  103. package/documentation/doc-util/doc-functions.js +65 -0
  104. package/documentation/doc-util/doc-normalized-ast.js +3 -2
  105. package/documentation/doc-util/doc-print.d.ts +5 -0
  106. package/documentation/doc-util/doc-print.js +36 -0
  107. package/documentation/doc-util/doc-query.js +3 -2
  108. package/documentation/doc-util/doc-repl.js +2 -1
  109. package/documentation/doc-util/doc-search.js +3 -2
  110. package/documentation/doc-util/doc-types.d.ts +28 -6
  111. package/documentation/doc-util/doc-types.js +89 -45
  112. package/documentation/print-cfg-wiki.js +6 -7
  113. package/documentation/print-core-wiki.js +5 -5
  114. package/documentation/print-dataflow-graph-wiki.js +10 -10
  115. package/documentation/print-engines-wiki.js +1 -2
  116. package/documentation/print-faq-wiki.js +8 -2
  117. package/documentation/print-interface-wiki.js +1 -2
  118. package/documentation/print-linter-issue.d.ts +1 -0
  119. package/documentation/print-linter-issue.js +71 -0
  120. package/documentation/print-linter-wiki.js +219 -34
  121. package/documentation/print-linting-and-testing-wiki.js +2 -4
  122. package/documentation/print-normalized-ast-wiki.js +3 -3
  123. package/documentation/print-query-wiki.js +1 -2
  124. package/documentation/print-readme.js +24 -1
  125. package/documentation/print-search-wiki.js +1 -2
  126. package/linter/linter-executor.d.ts +3 -1
  127. package/linter/linter-executor.js +3 -2
  128. package/linter/linter-format.d.ts +67 -7
  129. package/linter/linter-format.js +12 -1
  130. package/linter/linter-rules.d.ts +155 -16
  131. package/linter/linter-rules.js +12 -4
  132. package/linter/linter-tags.d.ts +80 -0
  133. package/linter/linter-tags.js +85 -0
  134. package/linter/rules/absolute-path.d.ts +71 -0
  135. package/linter/rules/absolute-path.js +177 -0
  136. package/linter/rules/deprecated-functions.d.ts +43 -0
  137. package/linter/rules/deprecated-functions.js +58 -0
  138. package/linter/rules/{2-file-path-validity.d.ts → file-path-validity.d.ts} +16 -6
  139. package/linter/rules/{2-file-path-validity.js → file-path-validity.js} +21 -13
  140. package/linter/rules/naming-convention.d.ts +71 -0
  141. package/linter/rules/naming-convention.js +164 -0
  142. package/linter/rules/seeded-randomness.d.ts +65 -0
  143. package/linter/rules/seeded-randomness.js +122 -0
  144. package/linter/rules/unused-definition.d.ts +41 -0
  145. package/linter/rules/unused-definition.js +105 -0
  146. package/package.json +4 -1
  147. package/queries/base-query-format.d.ts +2 -0
  148. package/queries/catalog/call-context-query/call-context-query-executor.d.ts +1 -1
  149. package/queries/catalog/call-context-query/call-context-query-executor.js +2 -2
  150. package/queries/catalog/cluster-query/cluster-query-format.d.ts +1 -1
  151. package/queries/catalog/config-query/config-query-executor.d.ts +1 -1
  152. package/queries/catalog/config-query/config-query-executor.js +2 -3
  153. package/queries/catalog/control-flow-query/control-flow-query-executor.d.ts +1 -1
  154. package/queries/catalog/control-flow-query/control-flow-query-executor.js +2 -2
  155. package/queries/catalog/control-flow-query/control-flow-query-format.d.ts +1 -1
  156. package/queries/catalog/dataflow-lens-query/dataflow-lens-query-format.d.ts +1 -1
  157. package/queries/catalog/dataflow-query/dataflow-query-format.d.ts +1 -1
  158. package/queries/catalog/dependencies-query/dependencies-query-executor.js +4 -116
  159. package/queries/catalog/dependencies-query/dependencies-query-format.d.ts +1 -1
  160. package/queries/catalog/happens-before-query/happens-before-query-format.d.ts +1 -1
  161. package/queries/catalog/id-map-query/id-map-query-format.d.ts +1 -1
  162. package/queries/catalog/lineage-query/lineage-query-format.d.ts +1 -1
  163. package/queries/catalog/linter-query/linter-query-executor.d.ts +1 -1
  164. package/queries/catalog/linter-query/linter-query-executor.js +2 -2
  165. package/queries/catalog/linter-query/linter-query-format.d.ts +1 -1
  166. package/queries/catalog/linter-query/linter-query-format.js +16 -12
  167. package/queries/catalog/normalized-ast-query/normalized-ast-query-format.d.ts +1 -1
  168. package/queries/catalog/origin-query/origin-query-format.d.ts +1 -1
  169. package/queries/catalog/project-query/project-query-format.d.ts +1 -1
  170. package/queries/catalog/resolve-value-query/resolve-value-query-executor.d.ts +1 -1
  171. package/queries/catalog/resolve-value-query/resolve-value-query-executor.js +2 -2
  172. package/queries/catalog/resolve-value-query/resolve-value-query-format.d.ts +1 -1
  173. package/queries/catalog/search-query/search-query-executor.d.ts +1 -1
  174. package/queries/catalog/search-query/search-query-executor.js +2 -2
  175. package/queries/catalog/search-query/search-query-format.d.ts +1 -1
  176. package/queries/catalog/static-slice-query/static-slice-query-executor.d.ts +1 -1
  177. package/queries/catalog/static-slice-query/static-slice-query-executor.js +2 -2
  178. package/queries/catalog/static-slice-query/static-slice-query-format.d.ts +1 -1
  179. package/queries/query.d.ts +15 -15
  180. package/r-bridge/lang-4.x/ast/parser/json/parser.d.ts +2 -1
  181. package/r-bridge/lang-4.x/ast/parser/json/parser.js +4 -2
  182. package/r-bridge/lang-4.x/convert-values.js +2 -1
  183. package/r-bridge/lang-4.x/tree-sitter/tree-sitter-executor.d.ts +3 -1
  184. package/r-bridge/lang-4.x/tree-sitter/tree-sitter-executor.js +4 -4
  185. package/r-bridge/lang-4.x/tree-sitter/tree-sitter-normalize.d.ts +1 -1
  186. package/r-bridge/lang-4.x/tree-sitter/tree-sitter-normalize.js +7 -5
  187. package/r-bridge/shell.d.ts +3 -2
  188. package/r-bridge/shell.js +4 -5
  189. package/search/flowr-search-builder.d.ts +6 -2
  190. package/search/flowr-search-builder.js +7 -0
  191. package/search/flowr-search-filters.d.ts +32 -8
  192. package/search/flowr-search-filters.js +42 -15
  193. package/search/flowr-search.d.ts +4 -0
  194. package/search/search-executor/search-enrichers.d.ts +7 -3
  195. package/search/search-executor/search-enrichers.js +29 -20
  196. package/search/search-executor/search-generators.js +1 -1
  197. package/search/search-executor/search-transformer.d.ts +2 -0
  198. package/search/search-executor/search-transformer.js +10 -1
  199. package/slicing/static/static-slicer.d.ts +1 -1
  200. package/slicing/static/static-slicer.js +2 -3
  201. package/statistics/statistics.d.ts +3 -1
  202. package/statistics/statistics.js +5 -4
  203. package/util/containers.d.ts +12 -9
  204. package/util/containers.js +12 -9
  205. package/util/objects.d.ts +5 -4
  206. package/util/range.d.ts +5 -1
  207. package/util/range.js +11 -3
  208. package/util/text/strings.d.ts +6 -0
  209. package/util/text/strings.js +35 -0
  210. package/util/version.js +1 -1
  211. package/linter/rules/1-deprecated-functions.d.ts +0 -34
  212. package/linter/rules/1-deprecated-functions.js +0 -54
@@ -7,6 +7,7 @@ exports.boolean2ts = boolean2ts;
7
7
  exports.number2ts = number2ts;
8
8
  exports.string2ts = string2ts;
9
9
  exports.isNA = isNA;
10
+ const strings_1 = require("../../util/text/strings");
10
11
  class ValueConversionError extends Error {
11
12
  constructor(message) {
12
13
  super(message);
@@ -136,7 +137,7 @@ function string2ts(value) {
136
137
  const flags = value[1];
137
138
  if (flags === '"' || flags === '\'') {
138
139
  return {
139
- str: value.slice(2, -1),
140
+ str: (0, strings_1.dropRawStringSurround)(value.slice(2, -1)),
140
141
  quotes: flags,
141
142
  flag: 'raw'
142
143
  };
@@ -1,6 +1,7 @@
1
1
  import Parser from 'web-tree-sitter';
2
2
  import type { RParseRequest } from '../../retriever';
3
3
  import type { SyncParser } from '../../parser';
4
+ import type { TreeSitterEngineConfig } from '../../../config';
4
5
  export declare const DEFAULT_TREE_SITTER_R_WASM_PATH = "./node_modules/@eagleoutice/tree-sitter-r/tree-sitter-r.wasm";
5
6
  export declare const DEFAULT_TREE_SITTER_WASM_PATH = "./node_modules/web-tree-sitter/tree-sitter.wasm";
6
7
  /**
@@ -12,10 +13,11 @@ export declare class TreeSitterExecutor implements SyncParser<Parser.Tree> {
12
13
  private static language;
13
14
  /**
14
15
  * Initializes the underlying tree-sitter parser. This only needs to be called once globally.
16
+ * @param config - The configuration for the tree-sitter engine, which can include paths to the wasm files.
15
17
  * @param overrideWasmPath - The path to the tree-sitter-r wasm file, which takes precedence over the config and default paths if set.
16
18
  * @param overrideTreeSitterWasmPath - The path to the tree-sitter wasm file, which takes precedence over the config and default paths if set.
17
19
  */
18
- static initTreeSitter(overrideWasmPath?: string, overrideTreeSitterWasmPath?: string): Promise<void>;
20
+ static initTreeSitter(config?: TreeSitterEngineConfig, overrideWasmPath?: string, overrideTreeSitterWasmPath?: string): Promise<void>;
19
21
  constructor();
20
22
  rVersion(): Promise<string | 'unknown' | 'none'>;
21
23
  treeSitterVersion(): number;
@@ -6,7 +6,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.TreeSitterExecutor = exports.DEFAULT_TREE_SITTER_WASM_PATH = exports.DEFAULT_TREE_SITTER_R_WASM_PATH = void 0;
7
7
  const web_tree_sitter_1 = __importDefault(require("web-tree-sitter"));
8
8
  const fs_1 = __importDefault(require("fs"));
9
- const config_1 = require("../../../config");
10
9
  const log_1 = require("../../../util/log");
11
10
  exports.DEFAULT_TREE_SITTER_R_WASM_PATH = './node_modules/@eagleoutice/tree-sitter-r/tree-sitter-r.wasm';
12
11
  exports.DEFAULT_TREE_SITTER_WASM_PATH = './node_modules/web-tree-sitter/tree-sitter.wasm';
@@ -20,11 +19,12 @@ class TreeSitterExecutor {
20
19
  static language;
21
20
  /**
22
21
  * Initializes the underlying tree-sitter parser. This only needs to be called once globally.
22
+ * @param config - The configuration for the tree-sitter engine, which can include paths to the wasm files.
23
23
  * @param overrideWasmPath - The path to the tree-sitter-r wasm file, which takes precedence over the config and default paths if set.
24
24
  * @param overrideTreeSitterWasmPath - The path to the tree-sitter wasm file, which takes precedence over the config and default paths if set.
25
25
  */
26
- static async initTreeSitter(overrideWasmPath, overrideTreeSitterWasmPath) {
27
- const treeSitterWasmPath = overrideTreeSitterWasmPath ?? (0, config_1.getEngineConfig)('tree-sitter')?.treeSitterWasmPath ?? exports.DEFAULT_TREE_SITTER_WASM_PATH;
26
+ static async initTreeSitter(config, overrideWasmPath, overrideTreeSitterWasmPath) {
27
+ const treeSitterWasmPath = overrideTreeSitterWasmPath ?? config?.treeSitterWasmPath ?? exports.DEFAULT_TREE_SITTER_WASM_PATH;
28
28
  // noinspection JSUnusedGlobalSymbols - this is used by emscripten, see https://emscripten.org/docs/api_reference/module.html
29
29
  await web_tree_sitter_1.default.init({
30
30
  locateFile: treeSitterWasmPath ? (path, prefix) => {
@@ -38,7 +38,7 @@ class TreeSitterExecutor {
38
38
  print: (s) => wasmLog.debug(s),
39
39
  printErr: (s) => wasmLog.error(s)
40
40
  });
41
- const wasmPath = overrideWasmPath ?? (0, config_1.getEngineConfig)('tree-sitter')?.wasmPath ?? exports.DEFAULT_TREE_SITTER_R_WASM_PATH;
41
+ const wasmPath = overrideWasmPath ?? config?.wasmPath ?? exports.DEFAULT_TREE_SITTER_R_WASM_PATH;
42
42
  TreeSitterExecutor.language = await web_tree_sitter_1.default.Language.load(wasmPath);
43
43
  }
44
44
  constructor() {
@@ -3,6 +3,6 @@ import type { Tree } from 'web-tree-sitter';
3
3
  /**
4
4
  * @param tree - The tree to normalize
5
5
  */
6
- export declare function normalizeTreeSitterTreeToAst(tree: Tree): RExpressionList;
6
+ export declare function normalizeTreeSitterTreeToAst(tree: Tree, lax?: boolean): RExpressionList;
7
7
  export declare function makeTreeSitterLax(): void;
8
8
  export declare function makeTreeSitterStrict(): void;
@@ -12,13 +12,11 @@ const normalize_meta_1 = require("../ast/parser/main/normalize-meta");
12
12
  const arrays_1 = require("../../../util/collections/arrays");
13
13
  const r_function_call_1 = require("../ast/model/nodes/r-function-call");
14
14
  const strings_1 = require("../../../util/text/strings");
15
- const config_1 = require("../../../config");
16
15
  const log_1 = require("../../../util/log");
17
16
  /**
18
17
  * @param tree - The tree to normalize
19
18
  */
20
- function normalizeTreeSitterTreeToAst(tree) {
21
- const lax = (0, config_1.getEngineConfig)('tree-sitter')?.lax;
19
+ function normalizeTreeSitterTreeToAst(tree, lax) {
22
20
  if (lax) {
23
21
  makeTreeSitterLax();
24
22
  }
@@ -343,14 +341,18 @@ function convertTreeNode(node) {
343
341
  }
344
342
  case tree_sitter_types_1.TreeSitterType.FunctionDefinition: {
345
343
  const [name, paramsParens, body] = nonErrorChildren(node);
346
- const params = (0, arrays_1.splitArrayOn)(paramsParens.children.slice(1, -1), x => x.type === 'comma');
344
+ const [comments, noCommentRawParams] = splitComments(paramsParens.children.slice(1, -1));
345
+ const params = (0, arrays_1.splitArrayOn)(noCommentRawParams, x => x.type === 'comma');
347
346
  return {
348
347
  type: type_1.RType.FunctionDefinition,
349
348
  parameters: params.map(n => convertTreeNode(n[0])),
350
349
  body: (0, normalize_meta_1.ensureExpressionList)(convertTreeNode(body)),
351
350
  location: makeSourceRange(name),
352
351
  lexeme: name.text,
353
- ...defaultInfo
352
+ info: {
353
+ ...defaultInfo.info,
354
+ additionalTokens: comments.map(c => c[1]),
355
+ }
354
356
  };
355
357
  }
356
358
  case tree_sitter_types_1.TreeSitterType.String:
@@ -1,6 +1,7 @@
1
1
  import { type MergeableRecord } from '../util/objects';
2
2
  import type { SemVer } from 'semver';
3
3
  import type { AsyncOrSync } from 'ts-essentials';
4
+ import type { RShellEngineConfig } from '../config';
4
5
  import type { AsyncParser } from './parser';
5
6
  import type { RParseRequest } from './retriever';
6
7
  export type OutputStreamSelector = 'stdout' | 'stderr' | 'both';
@@ -68,7 +69,7 @@ export interface RShellOptions extends RShellSessionOptions {
68
69
  readonly sessionName: string;
69
70
  }
70
71
  export declare const DEFAULT_R_PATH: string;
71
- export declare function getDefaultRShellOptions(): RShellOptions;
72
+ export declare function getDefaultRShellOptions(config?: RShellEngineConfig): RShellOptions;
72
73
  /**
73
74
  * The `RShell` represents an interactive session with the R interpreter.
74
75
  * You can configure it by {@link RShellOptions}.
@@ -85,7 +86,7 @@ export declare class RShell implements AsyncParser<string> {
85
86
  private readonly log;
86
87
  private versionCache;
87
88
  private tempDirs;
88
- constructor(options?: Partial<RShellOptions>);
89
+ constructor(config?: RShellEngineConfig, options?: Partial<RShellOptions>);
89
90
  parse(request: RParseRequest): Promise<string>;
90
91
  private revive;
91
92
  /**
package/r-bridge/shell.js CHANGED
@@ -46,7 +46,6 @@ const preload_1 = __importDefault(require("semver/preload"));
46
46
  const os_1 = require("../util/os");
47
47
  const fs_1 = __importDefault(require("fs"));
48
48
  const init_1 = require("./init");
49
- const config_1 = require("../config");
50
49
  const convert_values_1 = require("./lang-4.x/convert-values");
51
50
  const retriever_1 = require("./retriever");
52
51
  exports.DEFAULT_OUTPUT_COLLECTOR_CONFIGURATION = {
@@ -62,10 +61,10 @@ exports.DEFAULT_OUTPUT_COLLECTOR_CONFIGURATION = {
62
61
  };
63
62
  exports.DEFAULT_R_PATH = (0, os_1.getPlatform)() === 'windows' ? 'R.exe' : 'R';
64
63
  let DEFAULT_R_SHELL_OPTIONS = undefined;
65
- function getDefaultRShellOptions() {
64
+ function getDefaultRShellOptions(config) {
66
65
  if (!DEFAULT_R_SHELL_OPTIONS) {
67
66
  DEFAULT_R_SHELL_OPTIONS = {
68
- pathToRExecutable: (0, config_1.getEngineConfig)('r-shell')?.rPath ?? exports.DEFAULT_R_PATH,
67
+ pathToRExecutable: config?.rPath ?? exports.DEFAULT_R_PATH,
69
68
  // -s is a short form of --no-echo (and the old version --slave), but this one works in R 3 and 4
70
69
  // (see https://github.com/wch/r-source/commit/f1ff49e74593341c74c20de9517f31a22c8bcb04)
71
70
  commandLineOptions: ['--vanilla', '--quiet', '--no-save', '-s'],
@@ -97,8 +96,8 @@ class RShell {
97
96
  versionCache = null;
98
97
  // should never be more than one, but let's be sure
99
98
  tempDirs = new Set();
100
- constructor(options) {
101
- this.options = { ...getDefaultRShellOptions(), ...options };
99
+ constructor(config, options) {
100
+ this.options = { ...getDefaultRShellOptions(config), ...options };
102
101
  this.log = log_1.log.getSubLogger({ name: this.options.sessionName });
103
102
  this.session = new RShellSession(this.options, this.log);
104
103
  this.revive();
@@ -1,6 +1,6 @@
1
1
  import type { NodeId } from '../r-bridge/lang-4.x/ast/model/processing/node-id';
2
2
  import type { FlowrSearchElement, FlowrSearchElementFromQuery, FlowrSearchElements, FlowrSearchGetFilter } from './flowr-search';
3
- import type { FlowrFilterExpression } from './flowr-search-filters';
3
+ import type { FlowrFilter, FlowrFilterExpression } from './flowr-search-filters';
4
4
  import type { FlowrSearchGeneratorNode, GeneratorNames } from './search-executor/search-generators';
5
5
  import type { FlowrSearchTransformerNode, GetOutputOfTransformer, TransformerNames } from './search-executor/search-transformer';
6
6
  import type { SlicingCriteria } from '../slicing/criterion/parse';
@@ -155,7 +155,7 @@ export declare class FlowrSearchBuilder<Generator extends GeneratorNames, Transf
155
155
  /**
156
156
  * only returns the elements that match the given filter.
157
157
  */
158
- filter(filter: FlowrFilterExpression): FlowrSearchBuilderOut<Generator, Transformers, Info, 'filter'>;
158
+ filter<Filter extends FlowrFilter>(filter: FlowrFilterExpression<Filter>): FlowrSearchBuilderOut<Generator, Transformers, Info, 'filter'>;
159
159
  /**
160
160
  * first either returns the first element of the search or nothing, if no elements are present.
161
161
  */
@@ -201,6 +201,10 @@ export declare class FlowrSearchBuilder<Generator extends GeneratorNames, Transf
201
201
  * merge combines the search results with those of another search.
202
202
  */
203
203
  merge<Generator2 extends GeneratorNames, Transformers2 extends TransformerNames[], OtherElementType extends FlowrSearchElements<Info, FlowrSearchElement<Info>[]>>(other: FlowrSearchBuilder<Generator2, Transformers2, Info, OtherElementType>): FlowrSearchBuilder<Generator, Transformers, Info>;
204
+ /**
205
+ * Removes duplicate elements based on the ids of the elements.
206
+ */
207
+ unique(): FlowrSearchBuilderOut<Generator, Transformers, Info, 'unique'>;
204
208
  /**
205
209
  * Construct the final search (this may happen automatically with most search handlers).
206
210
  *
@@ -195,6 +195,13 @@ class FlowrSearchBuilder {
195
195
  this.search.push({ type: 'transformer', name: 'merge', args: { generator: other.generator, search: other.search } });
196
196
  return this;
197
197
  }
198
+ /**
199
+ * Removes duplicate elements based on the ids of the elements.
200
+ */
201
+ unique() {
202
+ this.search.push({ type: 'transformer', name: 'unique', args: undefined });
203
+ return this;
204
+ }
198
205
  /**
199
206
  * Construct the final search (this may happen automatically with most search handlers).
200
207
  *
@@ -2,23 +2,47 @@ import { RType } from '../r-bridge/lang-4.x/ast/model/type';
2
2
  import type { VertexType } from '../dataflow/graph/vertex';
3
3
  import type { NormalizedAst, ParentInformation } from '../r-bridge/lang-4.x/ast/model/processing/decorate';
4
4
  import type { DataflowInformation } from '../dataflow/info';
5
- import type { RNode } from '../r-bridge/lang-4.x/ast/model/model';
5
+ import type { FlowrSearchElement } from './flowr-search';
6
+ import type { MergeableRecord } from '../util/objects';
7
+ import type { Enrichment } from './search-executor/search-enrichers';
6
8
  export type FlowrFilterName = keyof typeof FlowrFilters;
9
+ interface FlowrFilterWithArgs<Filter extends FlowrFilterName, Args extends FlowrFilterArgs<Filter>> {
10
+ name: Filter;
11
+ args: Args;
12
+ }
7
13
  export declare enum FlowrFilter {
8
- DropEmptyArguments = "drop-empty-arguments"
14
+ /**
15
+ * Drops search elements that represent empty arguments. Specifically, all nodes that are arguments and have an undefined name are skipped.
16
+ * This filter does not accept any arguments.
17
+ */
18
+ DropEmptyArguments = "drop-empty-arguments",
19
+ /**
20
+ * Only returns search elements whose enrichments' JSON representations match a given test regular expression.
21
+ * 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.
22
+ * To test for included function names in an enrichment like {@link Enrichment.CallTargets}, the helper function {@link testFunctionsIgnoringPackage} can be used.
23
+ */
24
+ MatchesEnrichment = "matches-enrichment"
9
25
  }
26
+ export type FlowrFilterFunction<T extends MergeableRecord> = (e: FlowrSearchElement<ParentInformation>, args: T) => boolean;
10
27
  export declare const ValidFlowrFilters: Set<string>;
11
28
  export declare const ValidFlowrFiltersReverse: {
12
29
  [k: string]: string;
13
30
  };
14
31
  export declare const FlowrFilters: {
15
- readonly "drop-empty-arguments": (n: RNode<ParentInformation>) => boolean;
32
+ readonly "drop-empty-arguments": (e: FlowrSearchElement<ParentInformation>, _args: never) => boolean;
33
+ readonly "matches-enrichment": (e: FlowrSearchElement<ParentInformation>, args: MatchesEnrichmentArgs<Enrichment>) => boolean;
16
34
  };
17
- type ValidFilterTypes = FlowrFilterName | RType | VertexType;
35
+ export type FlowrFilterArgs<F extends FlowrFilter> = typeof FlowrFilters[F] extends FlowrFilterFunction<infer Args> ? Args : never;
36
+ export interface MatchesEnrichmentArgs<E extends Enrichment> extends MergeableRecord {
37
+ enrichment: E;
38
+ test: RegExp;
39
+ }
40
+ export declare function testFunctionsIgnoringPackage(functions: string[]): RegExp;
41
+ type ValidFilterTypes<F extends FlowrFilter = FlowrFilter> = FlowrFilterName | FlowrFilterWithArgs<F, FlowrFilterArgs<F>> | RType | VertexType;
18
42
  /**
19
43
  * By default, we provide filter for every {@link RType} and {@link VertexType}.
20
44
  */
21
- export type FlowrFilterExpression = FlowrFilterCombinator | ValidFilterTypes;
45
+ export type FlowrFilterExpression<F extends FlowrFilter = FlowrFilter> = FlowrFilterCombinator | ValidFilterTypes<F>;
22
46
  interface BooleanBinaryNode<Composite> {
23
47
  readonly type: 'and' | 'or' | 'xor';
24
48
  readonly left: Composite;
@@ -38,7 +62,7 @@ type LeafVertexType = {
38
62
  };
39
63
  type LeafSpecial = {
40
64
  readonly type: 'special';
41
- readonly value: string;
65
+ readonly value: FlowrFilterName | FlowrFilterWithArgs<FlowrFilter, FlowrFilterArgs<FlowrFilter>>;
42
66
  };
43
67
  type Leaf = LeafRType | LeafVertexType | LeafSpecial;
44
68
  type BooleanNode = BooleanBinaryNode<BooleanNode> | BooleanUnaryNode<BooleanNode> | Leaf;
@@ -66,9 +90,9 @@ export declare function isBinaryTree(tree: unknown): tree is {
66
90
  tree: BooleanNode;
67
91
  };
68
92
  interface FilterData {
69
- readonly node: RNode<ParentInformation>;
93
+ readonly element: FlowrSearchElement<ParentInformation>;
70
94
  readonly normalize: NormalizedAst;
71
95
  readonly dataflow: DataflowInformation;
72
96
  }
73
- export declare function evalFilter(filter: FlowrFilterExpression, data: FilterData): boolean;
97
+ export declare function evalFilter<Filter extends FlowrFilter>(filter: FlowrFilterExpression<Filter>, data: FilterData): boolean;
74
98
  export {};
@@ -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
  };
@@ -24,7 +24,7 @@ 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);
@@ -32,34 +32,42 @@ exports.Enrichments = {
32
32
  const origins = (0, dfg_get_origin_1.getOriginInDfg)(data.dataflow.graph, callVertex.id);
33
33
  if (!origins || origins.length === 0) {
34
34
  content.targets = [(0, node_id_1.recoverName)(callVertex.id, data.normalize.idMap)];
35
- return content;
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));
50
- if (content.targets.length === 0) {
51
- content.targets = [(0, node_id_1.recoverName)(callVertex.id, data.normalize.idMap)];
52
53
  }
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);
61
+ }
54
62
  return content;
55
63
  },
56
64
  // as built-in call target enrichments are not nodes, we don't return them as part of the mapper!
57
65
  mapper: ({ targets }) => targets.map(t => t).filter(t => t.node !== undefined)
58
66
  },
59
67
  [Enrichment.LastCall]: {
60
- enrich: (e, data, args) => {
68
+ enrich: (e, data, args, prev) => {
61
69
  (0, assert_1.guard)(args && args.length, `${Enrichment.LastCall} enrichment requires at least one argument`);
62
- const content = { linkedIds: [] };
70
+ const content = prev ?? { linkedIds: [] };
63
71
  const vertex = data.dataflow.graph.get(e.node.info.id);
64
72
  if (vertex !== undefined && vertex[0].tag === vertex_1.VertexType.FunctionCall) {
65
73
  const cfg = (0, extract_cfg_1.extractSimpleCfg)(data.normalize);
@@ -90,11 +98,12 @@ function enrichmentContent(e, enrichment) {
90
98
  }
91
99
  function enrich(e, data, enrichment, args) {
92
100
  const enrichmentData = exports.Enrichments[enrichment];
101
+ const prev = e?.enrichments;
93
102
  return {
94
103
  ...e,
95
104
  enrichments: {
96
- ...e?.enrichments ?? {},
97
- [enrichment]: enrichmentData.enrich(e, data, args)
105
+ ...prev ?? {},
106
+ [enrichment]: enrichmentData.enrich(e, data, args, prev?.[enrichment])
98
107
  }
99
108
  };
100
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
@@ -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(', ')}`);