@eagleoutice/flowr 2.1.11 → 2.2.0

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 (137) hide show
  1. package/benchmark/slicer.d.ts +5 -12
  2. package/benchmark/slicer.js +46 -28
  3. package/cli/benchmark-app.d.ts +2 -0
  4. package/cli/benchmark-app.js +2 -1
  5. package/cli/benchmark-helper-app.d.ts +2 -0
  6. package/cli/benchmark-helper-app.js +2 -2
  7. package/cli/common/options.js +3 -1
  8. package/cli/flowr-main-options.js +36 -2
  9. package/cli/flowr.d.ts +6 -0
  10. package/cli/flowr.js +51 -24
  11. package/cli/repl/commands/repl-cfg.js +2 -4
  12. package/cli/repl/commands/repl-dataflow.js +2 -4
  13. package/cli/repl/commands/repl-execute.d.ts +2 -2
  14. package/cli/repl/commands/repl-execute.js +15 -5
  15. package/cli/repl/commands/repl-lineage.js +2 -4
  16. package/cli/repl/commands/repl-main.d.ts +2 -2
  17. package/cli/repl/commands/repl-normalize.js +2 -4
  18. package/cli/repl/commands/repl-parse.js +2 -4
  19. package/cli/repl/commands/repl-query.js +7 -9
  20. package/cli/repl/commands/repl-version.d.ts +5 -4
  21. package/cli/repl/commands/repl-version.js +10 -9
  22. package/cli/repl/core.d.ts +5 -5
  23. package/cli/repl/core.js +8 -12
  24. package/cli/repl/print-version.d.ts +2 -2
  25. package/cli/repl/print-version.js +3 -3
  26. package/cli/repl/server/connection.d.ts +3 -3
  27. package/cli/repl/server/connection.js +6 -8
  28. package/cli/repl/server/messages/message-hello.js +2 -1
  29. package/cli/repl/server/server.d.ts +4 -3
  30. package/cli/repl/server/server.js +7 -5
  31. package/cli/slicer-app.js +1 -1
  32. package/config.d.ts +36 -4
  33. package/config.js +30 -1
  34. package/core/pipeline-executor.d.ts +1 -1
  35. package/core/pipeline-executor.js +1 -1
  36. package/core/steps/all/core/00-parse.d.ts +4 -18
  37. package/core/steps/all/core/00-parse.js +2 -11
  38. package/core/steps/all/core/01-parse-tree-sitter.d.ts +23 -0
  39. package/core/steps/all/core/01-parse-tree-sitter.js +19 -0
  40. package/core/steps/all/core/10-normalize.d.ts +3 -2
  41. package/core/steps/all/core/10-normalize.js +1 -0
  42. package/core/steps/all/core/11-normalize-tree-sitter.d.ts +25 -0
  43. package/core/steps/all/core/11-normalize-tree-sitter.js +27 -0
  44. package/core/steps/all/core/20-dataflow.d.ts +2 -0
  45. package/core/steps/all/core/20-dataflow.js +1 -1
  46. package/core/steps/pipeline/default-pipelines.d.ts +374 -23
  47. package/core/steps/pipeline/default-pipelines.js +48 -4
  48. package/dataflow/extractor.d.ts +2 -1
  49. package/dataflow/extractor.js +2 -1
  50. package/dataflow/graph/vertex.d.ts +4 -0
  51. package/dataflow/graph/vertex.js +3 -1
  52. package/dataflow/internal/process/functions/call/built-in/built-in-source.js +6 -5
  53. package/dataflow/processor.d.ts +2 -0
  54. package/documentation/doc-util/doc-auto-gen.js +2 -1
  55. package/documentation/doc-util/doc-cfg.js +1 -1
  56. package/documentation/doc-util/doc-dfg.js +3 -3
  57. package/documentation/doc-util/doc-files.d.ts +1 -0
  58. package/documentation/doc-util/doc-files.js +4 -0
  59. package/documentation/doc-util/doc-normalized-ast.js +2 -3
  60. package/documentation/doc-util/doc-query.js +2 -2
  61. package/documentation/doc-util/doc-search.d.ts +25 -0
  62. package/documentation/doc-util/doc-search.js +121 -0
  63. package/documentation/doc-util/doc-types.d.ts +10 -2
  64. package/documentation/doc-util/doc-types.js +81 -3
  65. package/documentation/print-dataflow-graph-wiki.js +16 -16
  66. package/documentation/print-engines-wiki.d.ts +1 -0
  67. package/documentation/print-engines-wiki.js +82 -0
  68. package/documentation/print-interface-wiki.js +30 -20
  69. package/documentation/print-normalized-ast-wiki.js +5 -5
  70. package/documentation/print-query-wiki.js +22 -0
  71. package/documentation/print-search-wiki.d.ts +1 -0
  72. package/documentation/print-search-wiki.js +74 -0
  73. package/package.json +10 -5
  74. package/queries/base-query-format.d.ts +2 -2
  75. package/queries/catalog/call-context-query/call-context-query-executor.d.ts +1 -1
  76. package/queries/catalog/call-context-query/call-context-query-executor.js +1 -1
  77. package/queries/catalog/cluster-query/cluster-query-executor.d.ts +1 -1
  78. package/queries/catalog/cluster-query/cluster-query-executor.js +1 -1
  79. package/queries/catalog/cluster-query/cluster-query-format.d.ts +5 -4
  80. package/queries/catalog/dataflow-query/dataflow-query-executor.d.ts +1 -1
  81. package/queries/catalog/dataflow-query/dataflow-query-executor.js +1 -1
  82. package/queries/catalog/dataflow-query/dataflow-query-format.d.ts +5 -4
  83. package/queries/catalog/dependencies-query/dependencies-query-executor.js +2 -2
  84. package/queries/catalog/dependencies-query/dependencies-query-format.d.ts +5 -4
  85. package/queries/catalog/id-map-query/id-map-query-format.d.ts +5 -4
  86. package/queries/catalog/lineage-query/lineage-query-executor.d.ts +1 -1
  87. package/queries/catalog/lineage-query/lineage-query-executor.js +1 -1
  88. package/queries/catalog/lineage-query/lineage-query-format.d.ts +5 -4
  89. package/queries/catalog/normalized-ast-query/normalized-ast-query-format.d.ts +5 -4
  90. package/queries/catalog/search-query/search-query-executor.d.ts +3 -0
  91. package/queries/catalog/search-query/search-query-executor.js +27 -0
  92. package/queries/catalog/search-query/search-query-format.d.ts +73 -0
  93. package/queries/catalog/search-query/search-query-format.js +29 -0
  94. package/queries/catalog/static-slice-query/static-slice-query-executor.d.ts +1 -1
  95. package/queries/catalog/static-slice-query/static-slice-query-executor.js +1 -1
  96. package/queries/catalog/static-slice-query/static-slice-query-format.d.ts +5 -4
  97. package/queries/query.d.ts +95 -29
  98. package/queries/query.js +3 -1
  99. package/r-bridge/lang-4.x/ast/model/type.d.ts +4 -0
  100. package/r-bridge/lang-4.x/ast/model/type.js +3 -1
  101. package/r-bridge/lang-4.x/ast/parser/json/parser.d.ts +4 -2
  102. package/r-bridge/lang-4.x/ast/parser/json/parser.js +5 -0
  103. package/r-bridge/lang-4.x/tree-sitter/tree-sitter-executor.d.ts +18 -0
  104. package/r-bridge/lang-4.x/tree-sitter/tree-sitter-executor.js +57 -0
  105. package/r-bridge/lang-4.x/tree-sitter/tree-sitter-normalize.d.ts +3 -0
  106. package/r-bridge/lang-4.x/tree-sitter/tree-sitter-normalize.js +541 -0
  107. package/r-bridge/lang-4.x/tree-sitter/tree-sitter-types.d.ts +35 -0
  108. package/r-bridge/lang-4.x/tree-sitter/tree-sitter-types.js +40 -0
  109. package/r-bridge/parser.d.ts +32 -0
  110. package/r-bridge/parser.js +14 -0
  111. package/r-bridge/shell-executor.d.ts +37 -1
  112. package/r-bridge/shell-executor.js +39 -0
  113. package/r-bridge/shell.d.ts +12 -6
  114. package/r-bridge/shell.js +15 -6
  115. package/search/flowr-search-builder.d.ts +193 -0
  116. package/search/flowr-search-builder.js +192 -0
  117. package/search/flowr-search-executor.d.ts +9 -0
  118. package/search/flowr-search-executor.js +16 -0
  119. package/search/flowr-search-filters.d.ts +74 -0
  120. package/search/flowr-search-filters.js +136 -0
  121. package/search/flowr-search-printer.d.ts +10 -0
  122. package/search/flowr-search-printer.js +85 -0
  123. package/search/flowr-search-traverse.d.ts +7 -0
  124. package/search/flowr-search-traverse.js +12 -0
  125. package/search/flowr-search.d.ts +58 -0
  126. package/search/flowr-search.js +29 -0
  127. package/search/search-executor/search-generators.d.ts +37 -0
  128. package/search/search-executor/search-generators.js +64 -0
  129. package/search/search-executor/search-transformer.d.ts +57 -0
  130. package/search/search-executor/search-transformer.js +99 -0
  131. package/search/search-optimizer/search-optimizer.d.ts +9 -0
  132. package/search/search-optimizer/search-optimizer.js +89 -0
  133. package/statistics/statistics.js +1 -1
  134. package/util/arrays.d.ts +13 -0
  135. package/util/assert.d.ts +1 -1
  136. package/util/mermaid/mermaid.js +17 -0
  137. package/util/version.js +1 -1
@@ -1,10 +1,46 @@
1
1
  import type { RShellExecutionOptions } from './shell';
2
2
  import type { SemVer } from 'semver';
3
- export declare class RShellExecutor {
3
+ import type { SyncParser } from './parser';
4
+ import { type RParseRequest } from './retriever';
5
+ /**
6
+ * This is a synchronous alternative to the {@link RShell}.
7
+ * Please be aware that using this is expensive.
8
+ * Every request effectively causes a new initialization of the R interpreter.
9
+ *
10
+ * With this class you can {@link RShellExecutor#run|run(command)} commands,
11
+ * that are potentially decorated with {@link RShellExecutor#addPrerequisites|prerequisites}.
12
+ * For compatibility,
13
+ * we provide {@link RShellExecutor#parse|parse(request)} and {@link RShellExecutor#rVersion|rVersion()}.
14
+ */
15
+ export declare class RShellExecutor implements SyncParser<string> {
16
+ readonly name = "r-shell";
4
17
  readonly options: Readonly<RShellExecutionOptions>;
5
18
  private readonly prerequisites;
6
19
  constructor(options?: Partial<RShellExecutionOptions>);
20
+ /**
21
+ * Adds commands that should be executed for every {@link RShellExecutor#run|run}.
22
+ */
7
23
  addPrerequisites(commands: string | string[]): this;
24
+ /**
25
+ * @returns the version of the R interpreter available to this executor.
26
+ *
27
+ * @see {@link RShellExecutor#usedRVersion}
28
+ * @see {@link RShell#rVersion}
29
+ * @see {@link RShell#usedRVersion}
30
+ */
31
+ rVersion(): Promise<string | 'unknown' | 'none'>;
32
+ /**
33
+ * Instead of returning a promise, this method returns the version of the R interpreter available to this executor,
34
+ * in the SemVer format.
35
+ */
8
36
  usedRVersion(): SemVer | null;
37
+ /**
38
+ * Runs the given command in the R interpreter.
39
+ */
9
40
  run(command: string, returnErr?: boolean): string;
41
+ /**
42
+ * Parses the given request and returns the result.
43
+ */
44
+ parse(request: RParseRequest): string;
45
+ close(): void;
10
46
  }
@@ -11,23 +11,55 @@ const preload_1 = __importDefault(require("semver/preload"));
11
11
  const log_1 = require("../util/log");
12
12
  const init_1 = require("./init");
13
13
  const convert_values_1 = require("./lang-4.x/convert-values");
14
+ const retriever_1 = require("./retriever");
14
15
  const executorLog = log_1.log.getSubLogger({ name: 'RShellExecutor' });
16
+ /**
17
+ * This is a synchronous alternative to the {@link RShell}.
18
+ * Please be aware that using this is expensive.
19
+ * Every request effectively causes a new initialization of the R interpreter.
20
+ *
21
+ * With this class you can {@link RShellExecutor#run|run(command)} commands,
22
+ * that are potentially decorated with {@link RShellExecutor#addPrerequisites|prerequisites}.
23
+ * For compatibility,
24
+ * we provide {@link RShellExecutor#parse|parse(request)} and {@link RShellExecutor#rVersion|rVersion()}.
25
+ */
15
26
  class RShellExecutor {
27
+ name = 'r-shell';
16
28
  options;
17
29
  prerequisites;
18
30
  constructor(options) {
19
31
  this.options = (0, objects_1.deepMergeObject)((0, shell_1.getDefaultRShellOptions)(), options);
20
32
  this.prerequisites = [(0, init_1.initCommand)(this.options.eol)];
21
33
  }
34
+ /**
35
+ * Adds commands that should be executed for every {@link RShellExecutor#run|run}.
36
+ */
22
37
  addPrerequisites(commands) {
23
38
  this.prerequisites.push(...(typeof commands == 'string' ? [commands] : commands));
24
39
  return this;
25
40
  }
41
+ /**
42
+ * @returns the version of the R interpreter available to this executor.
43
+ *
44
+ * @see {@link RShellExecutor#usedRVersion}
45
+ * @see {@link RShell#rVersion}
46
+ * @see {@link RShell#usedRVersion}
47
+ */
48
+ rVersion() {
49
+ return Promise.resolve(this.usedRVersion()?.format() ?? 'unknown');
50
+ }
51
+ /**
52
+ * Instead of returning a promise, this method returns the version of the R interpreter available to this executor,
53
+ * in the SemVer format.
54
+ */
26
55
  usedRVersion() {
27
56
  const version = this.run(`cat(paste0(R.version$major,".",R.version$minor), ${(0, convert_values_1.ts2r)(this.options.eol)})`);
28
57
  (0, log_1.expensiveTrace)(executorLog, () => `raw version: ${JSON.stringify(version)}`);
29
58
  return preload_1.default.coerce(version);
30
59
  }
60
+ /**
61
+ * Runs the given command in the R interpreter.
62
+ */
31
63
  run(command, returnErr = false) {
32
64
  command += ';base::quit()';
33
65
  (0, log_1.expensiveTrace)(executorLog, () => `> ${JSON.stringify(command)}`);
@@ -40,6 +72,13 @@ class RShellExecutor {
40
72
  });
41
73
  return (returnErr ? returns.stderr : returns.stdout).trim();
42
74
  }
75
+ /**
76
+ * Parses the given request and returns the result.
77
+ */
78
+ parse(request) {
79
+ return (0, retriever_1.retrieveParseDataFromRCode)(request, this);
80
+ }
81
+ close() { }
43
82
  }
44
83
  exports.RShellExecutor = RShellExecutor;
45
84
  //# sourceMappingURL=shell-executor.js.map
@@ -1,6 +1,8 @@
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 { AsyncParser } from './parser';
5
+ import type { RParseRequest } from './retriever';
4
6
  export type OutputStreamSelector = 'stdout' | 'stderr' | 'both';
5
7
  export interface CollectorTimeout extends MergeableRecord {
6
8
  /**
@@ -72,22 +74,26 @@ export declare function getDefaultRShellOptions(): RShellOptions;
72
74
  * You can configure it by {@link RShellOptions}.
73
75
  *
74
76
  * At the moment we are using a live R session (and not networking etc.) to communicate with R easily,
75
- * which allows us to install packages etc. However, this might and probably will change in the future (leaving this
76
- * as a legacy mode :D)
77
+ * which allows us to install packages etc. However, this might and probably will change in the future
78
+ * (leaving this as a legacy mode :D)
77
79
  */
78
- export declare class RShell {
80
+ export declare class RShell implements AsyncParser<string> {
81
+ readonly name = "r-shell";
82
+ readonly async = true;
79
83
  readonly options: Readonly<RShellOptions>;
80
84
  private session;
81
85
  private readonly log;
82
86
  private versionCache;
83
87
  private tempDirs;
84
88
  constructor(options?: Partial<RShellOptions>);
89
+ parse(request: RParseRequest): Promise<string>;
85
90
  private revive;
86
91
  /**
87
- * sends the given command directly to the current R session
88
- * will not do anything to alter input markers!
89
- */
92
+ * sends the given command directly to the current R session
93
+ * will not do anything to alter input markers!
94
+ */
90
95
  sendCommand(command: string): void;
96
+ rVersion(): Promise<string | 'unknown' | 'none'>;
91
97
  usedRVersion(): Promise<SemVer | null>;
92
98
  injectLibPaths(...paths: readonly string[]): void;
93
99
  tryToInjectHomeLibPath(): void;
package/r-bridge/shell.js CHANGED
@@ -38,6 +38,7 @@ const fs_1 = __importDefault(require("fs"));
38
38
  const init_1 = require("./init");
39
39
  const config_1 = require("../config");
40
40
  const convert_values_1 = require("./lang-4.x/convert-values");
41
+ const retriever_1 = require("./retriever");
41
42
  exports.DEFAULT_OUTPUT_COLLECTOR_CONFIGURATION = {
42
43
  from: 'stdout',
43
44
  postamble: `🐧${'-'.repeat(5)}🐧`,
@@ -54,7 +55,7 @@ let DEFAULT_R_SHELL_OPTIONS = undefined;
54
55
  function getDefaultRShellOptions() {
55
56
  if (!DEFAULT_R_SHELL_OPTIONS) {
56
57
  DEFAULT_R_SHELL_OPTIONS = {
57
- pathToRExecutable: (0, config_1.getConfig)().rPath ?? exports.DEFAULT_R_PATH,
58
+ pathToRExecutable: (0, config_1.getEngineConfig)('r-shell')?.rPath ?? exports.DEFAULT_R_PATH,
58
59
  // -s is a short form of --no-echo (and the old version --slave), but this one works in R 3 and 4
59
60
  // (see https://github.com/wch/r-source/commit/f1ff49e74593341c74c20de9517f31a22c8bcb04)
60
61
  commandLineOptions: ['--vanilla', '--quiet', '--no-save', '-s'],
@@ -74,10 +75,12 @@ function getDefaultRShellOptions() {
74
75
  * You can configure it by {@link RShellOptions}.
75
76
  *
76
77
  * At the moment we are using a live R session (and not networking etc.) to communicate with R easily,
77
- * which allows us to install packages etc. However, this might and probably will change in the future (leaving this
78
- * as a legacy mode :D)
78
+ * which allows us to install packages etc. However, this might and probably will change in the future
79
+ * (leaving this as a legacy mode :D)
79
80
  */
80
81
  class RShell {
82
+ name = 'r-shell';
83
+ async = true;
81
84
  options;
82
85
  session;
83
86
  log;
@@ -90,6 +93,9 @@ class RShell {
90
93
  this.session = new RShellSession(this.options, this.log);
91
94
  this.revive();
92
95
  }
96
+ parse(request) {
97
+ return (0, retriever_1.retrieveParseDataFromRCode)(request, this);
98
+ }
93
99
  revive() {
94
100
  if (this.options.revive === 0 /* RShellReviveOptions.Never */) {
95
101
  return;
@@ -104,15 +110,18 @@ class RShell {
104
110
  });
105
111
  }
106
112
  /**
107
- * sends the given command directly to the current R session
108
- * will not do anything to alter input markers!
109
- */
113
+ * sends the given command directly to the current R session
114
+ * will not do anything to alter input markers!
115
+ */
110
116
  sendCommand(command) {
111
117
  if (this.log.settings.minLevel <= 1 /* LogLevel.Trace */) {
112
118
  this.log.trace(`> ${JSON.stringify(command)}`);
113
119
  }
114
120
  this._sendCommand(command);
115
121
  }
122
+ async rVersion() {
123
+ return (await this.usedRVersion())?.format() ?? 'unknown';
124
+ }
116
125
  async usedRVersion() {
117
126
  if (this.versionCache !== null) {
118
127
  return this.versionCache;
@@ -0,0 +1,193 @@
1
+ import type { NodeId } from '../r-bridge/lang-4.x/ast/model/processing/node-id';
2
+ import type { FlowrSearchElement, FlowrSearchElements, FlowrSearchGetFilter } from './flowr-search';
3
+ import type { FlowrFilterExpression } from './flowr-search-filters';
4
+ import type { FlowrSearchGeneratorNode, GeneratorNames } from './search-executor/search-generators';
5
+ import type { FlowrSearchTransformerNode, GetOutputOfTransformer, TransformerNames } from './search-executor/search-transformer';
6
+ import type { SlicingCriteria } from '../slicing/criterion/parse';
7
+ import type { ParentInformation } from '../r-bridge/lang-4.x/ast/model/processing/decorate';
8
+ type FlowrCriteriaReturn<C extends SlicingCriteria> = FlowrSearchElements<ParentInformation, C extends [] ? never : C extends [infer _] ? [
9
+ FlowrSearchElement<ParentInformation>
10
+ ] : FlowrSearchElement<ParentInformation>[]>;
11
+ /**
12
+ * This object holds all the methods to generate search queries.
13
+ * For compatibility, please use the {@link Q} identifier object to access these methods.
14
+ */
15
+ export declare const FlowrSearchGenerator: {
16
+ /**
17
+ * Initialize a search query with the given elements.
18
+ * <b>This is not intended to serialize well</b> wrt. the nodes,
19
+ * see {@link FlowrSearchGenerator.criterion} for a serializable alternative (passing the ids with `$id`).
20
+ */
21
+ readonly from: (from: FlowrSearchElement<ParentInformation> | FlowrSearchElement<ParentInformation>[]) => FlowrSearchBuilder<"from">;
22
+ /**
23
+ * Returns all elements (nodes/dataflow vertices) from the given data.
24
+ */
25
+ readonly all: () => FlowrSearchBuilder<"all">;
26
+ /**
27
+ * Returns all elements that match the given {@link FlowrSearchGetFilters|filters}.
28
+ * You may pass a negative line number to count from the back.
29
+ * Please note that this is currently only working for single files, it approximates over the nodes, and it is not to be used for "production".
30
+ */
31
+ readonly get: (filter: FlowrSearchGetFilter) => FlowrSearchBuilder<"get">;
32
+ /**
33
+ * Returns all elements that match the given {@link SlicingCriteria|criteria}
34
+ * (e.g., `criterion('2@x', '3@<-')`,
35
+ * to retrieve the first use of `x` in the second line and the first `<-` assignment in the third line).
36
+ * This will throw an error, if any criteria cannot be resolved to an id.
37
+ */
38
+ readonly criterion: <Criteria extends SlicingCriteria>(...criterion: Criteria) => FlowrSearchBuilder<"criterion", [], ParentInformation, FlowrCriteriaReturn<Criteria>>;
39
+ /**
40
+ * Short form of {@link get} with only the
41
+ * {@link FlowrSearchGetFilters#line|line} and {@link FlowrSearchGetFilters#column|column} filters:
42
+ * `get({line, column})`.
43
+ */
44
+ readonly loc: (line?: number, column?: number) => FlowrSearchBuilder<"get">;
45
+ /**
46
+ * Short form of {@link get} with only the {@link FlowrSearchGetFilters#name|name} and {@link FlowrSearchGetFilters#line|line} filters:
47
+ * `get({name, line})`.
48
+ */
49
+ readonly varInLine: (name: string, line: number) => FlowrSearchBuilder<"get">;
50
+ /**
51
+ * Short form of {@link get} with only the {@link FlowrSearchGetFilters#name|name} filter:
52
+ * `get({name})`.
53
+ */
54
+ readonly var: (name: string) => FlowrSearchBuilder<"get">;
55
+ /**
56
+ * Short form of {@link get} with only the {@link FlowrSearchGetFilters#id|id} filter:
57
+ * `get({id})`.
58
+ */
59
+ readonly id: (id: NodeId) => FlowrSearchBuilder<"get">;
60
+ };
61
+ /**
62
+ * This is the root object to use for creating searches.
63
+ * See the {@link FlowrSearchGenerator} for the available methods.
64
+ * After the query is generated,
65
+ * you can use what is provided by the {@link FlowrSearchBuilder} to further refine the search.
66
+ */
67
+ export declare const Q: {
68
+ /**
69
+ * Initialize a search query with the given elements.
70
+ * <b>This is not intended to serialize well</b> wrt. the nodes,
71
+ * see {@link FlowrSearchGenerator.criterion} for a serializable alternative (passing the ids with `$id`).
72
+ */
73
+ readonly from: (from: FlowrSearchElement<ParentInformation> | FlowrSearchElement<ParentInformation>[]) => FlowrSearchBuilder<"from">;
74
+ /**
75
+ * Returns all elements (nodes/dataflow vertices) from the given data.
76
+ */
77
+ readonly all: () => FlowrSearchBuilder<"all">;
78
+ /**
79
+ * Returns all elements that match the given {@link FlowrSearchGetFilters|filters}.
80
+ * You may pass a negative line number to count from the back.
81
+ * Please note that this is currently only working for single files, it approximates over the nodes, and it is not to be used for "production".
82
+ */
83
+ readonly get: (filter: FlowrSearchGetFilter) => FlowrSearchBuilder<"get">;
84
+ /**
85
+ * Returns all elements that match the given {@link SlicingCriteria|criteria}
86
+ * (e.g., `criterion('2@x', '3@<-')`,
87
+ * to retrieve the first use of `x` in the second line and the first `<-` assignment in the third line).
88
+ * This will throw an error, if any criteria cannot be resolved to an id.
89
+ */
90
+ readonly criterion: <Criteria extends SlicingCriteria>(...criterion: Criteria) => FlowrSearchBuilder<"criterion", [], ParentInformation, FlowrCriteriaReturn<Criteria>>;
91
+ /**
92
+ * Short form of {@link get} with only the
93
+ * {@link FlowrSearchGetFilters#line|line} and {@link FlowrSearchGetFilters#column|column} filters:
94
+ * `get({line, column})`.
95
+ */
96
+ readonly loc: (line?: number, column?: number) => FlowrSearchBuilder<"get">;
97
+ /**
98
+ * Short form of {@link get} with only the {@link FlowrSearchGetFilters#name|name} and {@link FlowrSearchGetFilters#line|line} filters:
99
+ * `get({name, line})`.
100
+ */
101
+ readonly varInLine: (name: string, line: number) => FlowrSearchBuilder<"get">;
102
+ /**
103
+ * Short form of {@link get} with only the {@link FlowrSearchGetFilters#name|name} filter:
104
+ * `get({name})`.
105
+ */
106
+ readonly var: (name: string) => FlowrSearchBuilder<"get">;
107
+ /**
108
+ * Short form of {@link get} with only the {@link FlowrSearchGetFilters#id|id} filter:
109
+ * `get({id})`.
110
+ */
111
+ readonly id: (id: NodeId) => FlowrSearchBuilder<"get">;
112
+ };
113
+ export type FlowrSearchBuilderType<Generator extends GeneratorNames = GeneratorNames, Transformers extends TransformerNames[] = TransformerNames[], Info = ParentInformation, ElementType = FlowrSearchElements<Info, FlowrSearchElement<Info>[]>> = FlowrSearchBuilder<Generator, Transformers, Info, ElementType>;
114
+ type GetElements<F> = F extends FlowrSearchElements<infer Info, infer Elements> ? Elements extends FlowrSearchElement<Info>[] ? Elements : never : never;
115
+ /**
116
+ * The search query is a combination of a generator and a list of transformers
117
+ * and allows this view to pass such queries in a serialized form.
118
+ *
119
+ * @typeParam Transformers - The list of transformers that are applied to the generator's output.
120
+ */
121
+ export interface FlowrSearch<Info = ParentInformation, _Generator extends GeneratorNames = GeneratorNames, _Transformers extends readonly TransformerNames[] = readonly TransformerNames[], _ElementType = FlowrSearchElements<Info, FlowrSearchElement<Info>[]>> {
122
+ readonly generator: FlowrSearchGeneratorNode;
123
+ readonly search: readonly FlowrSearchTransformerNode[];
124
+ }
125
+ type FlowrSearchBuilderOut<Generator extends GeneratorNames, Transformers extends TransformerNames[], Info, Transformer extends TransformerNames> = FlowrSearchBuilder<Generator, [...Transformers, Transformer], Info, GetOutputOfTransformer<Transformer>>;
126
+ /**
127
+ * Allows you to construct a search query from a {@link FlowrSearchGeneratorNode}.
128
+ * Please use the {@link Q} object to create an object of this class!
129
+ * In the end, you _can_ freeze the search by calling {@link FlowrSearchBuilder#build},
130
+ * however, the search executors may do that for you.
131
+ *
132
+ * @see {@link FlowrSearchGenerator}
133
+ * @see {@link FlowrSearch}
134
+ * @see {@link FlowrSearchLike}
135
+ */
136
+ export declare class FlowrSearchBuilder<Generator extends GeneratorNames, Transformers extends TransformerNames[] = [], Info = ParentInformation, ElementType = FlowrSearchElements<Info, FlowrSearchElement<Info>[]>> {
137
+ private readonly generator;
138
+ private readonly search;
139
+ constructor(generator: FlowrSearchGeneratorNode);
140
+ /**
141
+ * only returns the elements that match the given filter.
142
+ */
143
+ filter(filter: FlowrFilterExpression): FlowrSearchBuilderOut<Generator, Transformers, Info, 'filter'>;
144
+ /**
145
+ * first either returns the first element of the search or nothing, if no elements are present.
146
+ */
147
+ first(): FlowrSearchBuilderOut<Generator, Transformers, Info, 'first'>;
148
+ /**
149
+ * last either returns the last element of the search or nothing, if no elements are present.
150
+ */
151
+ last(): FlowrSearchBuilderOut<Generator, Transformers, Info, 'last'>;
152
+ /**
153
+ * index returns the element at the given index if it exists
154
+ */
155
+ index<Idx extends number>(index: Idx): FlowrSearchBuilderOut<Generator, Transformers, Info, 'index'>;
156
+ /**
157
+ * tail returns all elements of the search except the first one.
158
+ */
159
+ tail(): FlowrSearchBuilderOut<Generator, Transformers, Info, 'tail'>;
160
+ /**
161
+ * take returns the first `count` elements of the search.
162
+ */
163
+ take<Count extends number>(count: Count): FlowrSearchBuilderOut<Generator, Transformers, Info, 'take'>;
164
+ /**
165
+ * skip returns all elements of the search except the first `count` ones.
166
+ */
167
+ skip<Count extends number>(count: Count): FlowrSearchBuilderOut<Generator, Transformers, Info, 'skip'>;
168
+ /**
169
+ * select returns only the elements at the given indices.
170
+ */
171
+ select<Select extends number[]>(...select: Select): FlowrSearchBuilderOut<Generator, Transformers, Info, 'select'>;
172
+ /**
173
+ * merge combines the search results with those of another search.
174
+ */
175
+ merge<Generator2 extends GeneratorNames, Transformers2 extends TransformerNames[], OtherElementType extends FlowrSearchElements<Info, FlowrSearchElement<Info>[]>>(other: FlowrSearchBuilder<Generator2, Transformers2, Info, OtherElementType>): FlowrSearchBuilder<Generator, Transformers, Info, FlowrSearchElements<Info, [...GetElements<ElementType>, ...GetElements<OtherElementType>]>>;
176
+ /**
177
+ * Construct the final search (this may happen automatically with most search handlers).
178
+ *
179
+ * @param shouldOptimize - This may optimize the search.
180
+ */
181
+ build(shouldOptimize?: boolean): FlowrSearch<Info, Generator, Transformers, ElementType>;
182
+ }
183
+ /**
184
+ * This type summarizes all types that can be used in places in which the API expects you to provide a search query.
185
+ * @see {@link FlowrSearch}
186
+ */
187
+ export type FlowrSearchLike = FlowrSearch | FlowrSearchBuilderType;
188
+ export type SearchOutput<Search> = Search extends FlowrSearch ? Search : Search extends FlowrSearchBuilderType<infer Generator, infer Transformers, infer Info, infer Elements> ? FlowrSearch<Info, Generator, Transformers, Elements> : never;
189
+ /**
190
+ * Freezes any accepted {@link FlowrSearchLike} into a {@link FlowrSearch}.
191
+ */
192
+ export declare function getFlowrSearch<Search extends FlowrSearchLike>(search: Search, optimizeIfBuild?: boolean): SearchOutput<Search>;
193
+ export {};
@@ -0,0 +1,192 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FlowrSearchBuilder = exports.Q = exports.FlowrSearchGenerator = void 0;
4
+ exports.getFlowrSearch = getFlowrSearch;
5
+ const search_optimizer_1 = require("./search-optimizer/search-optimizer");
6
+ const assert_1 = require("../util/assert");
7
+ /**
8
+ * This object holds all the methods to generate search queries.
9
+ * For compatibility, please use the {@link Q} identifier object to access these methods.
10
+ */
11
+ exports.FlowrSearchGenerator = {
12
+ /**
13
+ * Initialize a search query with the given elements.
14
+ * <b>This is not intended to serialize well</b> wrt. the nodes,
15
+ * see {@link FlowrSearchGenerator.criterion} for a serializable alternative (passing the ids with `$id`).
16
+ */
17
+ from(from) {
18
+ return new FlowrSearchBuilder({ type: 'generator', name: 'from', args: { from } });
19
+ },
20
+ /**
21
+ * Returns all elements (nodes/dataflow vertices) from the given data.
22
+ */
23
+ all() {
24
+ return new FlowrSearchBuilder({ type: 'generator', name: 'all', args: undefined });
25
+ },
26
+ /**
27
+ * Returns all elements that match the given {@link FlowrSearchGetFilters|filters}.
28
+ * You may pass a negative line number to count from the back.
29
+ * Please note that this is currently only working for single files, it approximates over the nodes, and it is not to be used for "production".
30
+ */
31
+ get(filter) {
32
+ (0, assert_1.guard)(!filter.nameIsRegex || filter.name, 'If nameIsRegex is set, a name should be provided');
33
+ (0, assert_1.guard)(!filter.line || filter.line != 0, 'If line is set, it must be different from 0 as there is no 0 line');
34
+ (0, assert_1.guard)(!filter.column || filter.column > 0, 'If column is set, it must be greater than 0, but was ' + filter.column);
35
+ return new FlowrSearchBuilder({ type: 'generator', name: 'get', args: { filter } });
36
+ },
37
+ /**
38
+ * Returns all elements that match the given {@link SlicingCriteria|criteria}
39
+ * (e.g., `criterion('2@x', '3@<-')`,
40
+ * to retrieve the first use of `x` in the second line and the first `<-` assignment in the third line).
41
+ * This will throw an error, if any criteria cannot be resolved to an id.
42
+ */
43
+ criterion(...criterion) {
44
+ (0, assert_1.guard)(criterion.length > 0, 'At least one criterion must be provided');
45
+ return new FlowrSearchBuilder({ type: 'generator', name: 'criterion', args: { criterion } });
46
+ },
47
+ /**
48
+ * Short form of {@link get} with only the
49
+ * {@link FlowrSearchGetFilters#line|line} and {@link FlowrSearchGetFilters#column|column} filters:
50
+ * `get({line, column})`.
51
+ */
52
+ loc(line, column) {
53
+ return exports.FlowrSearchGenerator.get({ line, column });
54
+ },
55
+ /**
56
+ * Short form of {@link get} with only the {@link FlowrSearchGetFilters#name|name} and {@link FlowrSearchGetFilters#line|line} filters:
57
+ * `get({name, line})`.
58
+ */
59
+ varInLine(name, line) {
60
+ return exports.FlowrSearchGenerator.get({ name, line });
61
+ },
62
+ /**
63
+ * Short form of {@link get} with only the {@link FlowrSearchGetFilters#name|name} filter:
64
+ * `get({name})`.
65
+ */
66
+ var(name) {
67
+ return exports.FlowrSearchGenerator.get({ name });
68
+ },
69
+ /**
70
+ * Short form of {@link get} with only the {@link FlowrSearchGetFilters#id|id} filter:
71
+ * `get({id})`.
72
+ */
73
+ id(id) {
74
+ return exports.FlowrSearchGenerator.get({ id });
75
+ }
76
+ };
77
+ /**
78
+ * This is the root object to use for creating searches.
79
+ * See the {@link FlowrSearchGenerator} for the available methods.
80
+ * After the query is generated,
81
+ * you can use what is provided by the {@link FlowrSearchBuilder} to further refine the search.
82
+ */
83
+ exports.Q = exports.FlowrSearchGenerator;
84
+ /**
85
+ * Allows you to construct a search query from a {@link FlowrSearchGeneratorNode}.
86
+ * Please use the {@link Q} object to create an object of this class!
87
+ * In the end, you _can_ freeze the search by calling {@link FlowrSearchBuilder#build},
88
+ * however, the search executors may do that for you.
89
+ *
90
+ * @see {@link FlowrSearchGenerator}
91
+ * @see {@link FlowrSearch}
92
+ * @see {@link FlowrSearchLike}
93
+ */
94
+ class FlowrSearchBuilder {
95
+ generator;
96
+ search = [];
97
+ constructor(generator) {
98
+ this.generator = generator;
99
+ }
100
+ /**
101
+ * only returns the elements that match the given filter.
102
+ */
103
+ filter(filter) {
104
+ this.search.push({ type: 'transformer', name: 'filter', args: { filter: filter } });
105
+ return this;
106
+ }
107
+ /**
108
+ * first either returns the first element of the search or nothing, if no elements are present.
109
+ */
110
+ first() {
111
+ this.search.push({ type: 'transformer', name: 'first', args: undefined });
112
+ return this;
113
+ }
114
+ /**
115
+ * last either returns the last element of the search or nothing, if no elements are present.
116
+ */
117
+ last() {
118
+ this.search.push({ type: 'transformer', name: 'last', args: undefined });
119
+ return this;
120
+ }
121
+ /**
122
+ * index returns the element at the given index if it exists
123
+ */
124
+ index(index) {
125
+ (0, assert_1.guard)(index >= 0, 'Index must be greater or equal to 0, but was ' + index);
126
+ this.search.push({ type: 'transformer', name: 'index', args: { index } });
127
+ return this;
128
+ }
129
+ /**
130
+ * tail returns all elements of the search except the first one.
131
+ */
132
+ tail() {
133
+ this.search.push({ type: 'transformer', name: 'tail', args: undefined });
134
+ return this;
135
+ }
136
+ /**
137
+ * take returns the first `count` elements of the search.
138
+ */
139
+ take(count) {
140
+ (0, assert_1.guard)(count >= 0, 'Count must be greater or equal to 0, but was ' + count);
141
+ this.search.push({ type: 'transformer', name: 'take', args: { count } });
142
+ return this;
143
+ }
144
+ /**
145
+ * skip returns all elements of the search except the first `count` ones.
146
+ */
147
+ skip(count) {
148
+ (0, assert_1.guard)(count >= 0, 'Count must be greater or equal to 0, but was ' + count);
149
+ this.search.push({ type: 'transformer', name: 'skip', args: { count } });
150
+ return this;
151
+ }
152
+ /**
153
+ * select returns only the elements at the given indices.
154
+ */
155
+ select(...select) {
156
+ (0, assert_1.guard)(select.length > 0, 'At least one index must be provided');
157
+ (0, assert_1.guard)(select.every(i => i >= 0), () => 'All indices must be greater or equal to 0, but were ' + JSON.stringify(select));
158
+ this.search.push({ type: 'transformer', name: 'select', args: { select } });
159
+ return this;
160
+ }
161
+ /**
162
+ * merge combines the search results with those of another search.
163
+ */
164
+ merge(other /* | FlowrSearch<Info, Generator2, Transformers2, OtherElementType> */
165
+ // @ts-expect-error -- this works when merging, there is no info disparity
166
+ ) {
167
+ this.search.push({ type: 'transformer', name: 'merge', args: { generator: other.generator, search: other.search } });
168
+ return this;
169
+ }
170
+ /**
171
+ * Construct the final search (this may happen automatically with most search handlers).
172
+ *
173
+ * @param shouldOptimize - This may optimize the search.
174
+ */
175
+ build(shouldOptimize = true) {
176
+ return shouldOptimize ? (0, search_optimizer_1.optimize)(this.generator, this.search) : {
177
+ generator: this.generator,
178
+ search: this.search
179
+ };
180
+ }
181
+ }
182
+ exports.FlowrSearchBuilder = FlowrSearchBuilder;
183
+ /**
184
+ * Freezes any accepted {@link FlowrSearchLike} into a {@link FlowrSearch}.
185
+ */
186
+ function getFlowrSearch(search, optimizeIfBuild = true) {
187
+ if (search instanceof FlowrSearchBuilder) {
188
+ return search.build(optimizeIfBuild);
189
+ }
190
+ return search;
191
+ }
192
+ //# sourceMappingURL=flowr-search-builder.js.map
@@ -0,0 +1,9 @@
1
+ import type { FlowrSearch, FlowrSearchLike, SearchOutput } from './flowr-search-builder';
2
+ import type { FlowrSearchElements, FlowrSearchInput } from './flowr-search';
3
+ import type { Pipeline } from '../core/steps/pipeline/pipeline';
4
+ type GetSearchElements<S> = S extends FlowrSearch<infer _, infer _, infer _, infer Elements> ? Elements extends FlowrSearchElements<infer _, infer E> ? E : never : never;
5
+ /**
6
+ * Run a search with the given search query and data.
7
+ */
8
+ export declare function runSearch<S extends FlowrSearchLike, P extends Pipeline>(search: S, data: FlowrSearchInput<P>): GetSearchElements<SearchOutput<S>>;
9
+ export {};
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.runSearch = runSearch;
4
+ const flowr_search_builder_1 = require("./flowr-search-builder");
5
+ const search_generators_1 = require("./search-executor/search-generators");
6
+ const search_transformer_1 = require("./search-executor/search-transformer");
7
+ /**
8
+ * Run a search with the given search query and data.
9
+ */
10
+ function runSearch(search, data) {
11
+ const s = (0, flowr_search_builder_1.getFlowrSearch)(search);
12
+ return s.search.reduce((acc, transformer) => (0, search_transformer_1.getTransformer)(transformer.name)(data, acc, transformer.args),
13
+ /* support multiple arguments may be abstracted away in search frontend */
14
+ (0, search_generators_1.getGenerator)(s.generator.name)(data, s.generator.args)).getElements();
15
+ }
16
+ //# sourceMappingURL=flowr-search-executor.js.map