@eagleoutice/flowr 2.1.10 → 2.1.12

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 (74) hide show
  1. package/README.md +1 -0
  2. package/cli/flowr.js +8 -0
  3. package/cli/repl/commands/repl-query.js +14 -3
  4. package/cli/repl/server/connection.js +1 -1
  5. package/core/steps/pipeline/default-pipelines.d.ts +6 -0
  6. package/core/steps/pipeline/default-pipelines.js +6 -0
  7. package/dataflow/environments/resolve-by-name.d.ts +2 -1
  8. package/dataflow/environments/resolve-by-name.js +2 -1
  9. package/dataflow/graph/vertex.d.ts +4 -0
  10. package/dataflow/graph/vertex.js +3 -1
  11. package/dataflow/internal/process/functions/call/built-in/built-in-access.js +29 -26
  12. package/dataflow/internal/process/functions/call/built-in/built-in-assignment.d.ts +1 -2
  13. package/dataflow/internal/process/functions/call/built-in/built-in-assignment.js +28 -24
  14. package/dataflow/internal/process/functions/call/built-in/built-in-replacement.js +2 -1
  15. package/documentation/doc-util/doc-dfg.js +1 -1
  16. package/documentation/doc-util/doc-query.js +1 -1
  17. package/documentation/doc-util/doc-search.d.ts +25 -0
  18. package/documentation/doc-util/doc-search.js +121 -0
  19. package/documentation/doc-util/doc-types.d.ts +10 -2
  20. package/documentation/doc-util/doc-types.js +81 -3
  21. package/documentation/print-dataflow-graph-wiki.js +1 -1
  22. package/documentation/print-interface-wiki.js +31 -15
  23. package/documentation/print-normalized-ast-wiki.js +4 -4
  24. package/documentation/print-query-wiki.js +35 -0
  25. package/documentation/print-search-wiki.d.ts +1 -0
  26. package/documentation/print-search-wiki.js +74 -0
  27. package/package.json +2 -1
  28. package/queries/base-query-format.d.ts +2 -2
  29. package/queries/catalog/call-context-query/call-context-query-executor.d.ts +1 -1
  30. package/queries/catalog/call-context-query/call-context-query-executor.js +1 -1
  31. package/queries/catalog/cluster-query/cluster-query-executor.d.ts +1 -1
  32. package/queries/catalog/cluster-query/cluster-query-executor.js +1 -1
  33. package/queries/catalog/config-query/config-query-executor.d.ts +3 -0
  34. package/queries/catalog/config-query/config-query-executor.js +18 -0
  35. package/queries/catalog/config-query/config-query-format.d.ts +16 -0
  36. package/queries/catalog/config-query/config-query-format.js +24 -0
  37. package/queries/catalog/dataflow-query/dataflow-query-executor.d.ts +1 -1
  38. package/queries/catalog/dataflow-query/dataflow-query-executor.js +1 -1
  39. package/queries/catalog/dependencies-query/dependencies-query-executor.js +2 -2
  40. package/queries/catalog/lineage-query/lineage-query-executor.d.ts +1 -1
  41. package/queries/catalog/lineage-query/lineage-query-executor.js +1 -1
  42. package/queries/catalog/location-map-query/location-map-query-format.js +1 -1
  43. package/queries/catalog/search-query/search-query-executor.d.ts +3 -0
  44. package/queries/catalog/search-query/search-query-executor.js +27 -0
  45. package/queries/catalog/search-query/search-query-format.d.ts +72 -0
  46. package/queries/catalog/search-query/search-query-format.js +29 -0
  47. package/queries/catalog/static-slice-query/static-slice-query-executor.d.ts +1 -1
  48. package/queries/catalog/static-slice-query/static-slice-query-executor.js +1 -1
  49. package/queries/query.d.ts +65 -1
  50. package/queries/query.js +5 -1
  51. package/r-bridge/lang-4.x/ast/model/type.d.ts +4 -0
  52. package/r-bridge/lang-4.x/ast/model/type.js +3 -1
  53. package/search/flowr-search-builder.d.ts +193 -0
  54. package/search/flowr-search-builder.js +192 -0
  55. package/search/flowr-search-executor.d.ts +9 -0
  56. package/search/flowr-search-executor.js +16 -0
  57. package/search/flowr-search-filters.d.ts +74 -0
  58. package/search/flowr-search-filters.js +136 -0
  59. package/search/flowr-search-printer.d.ts +10 -0
  60. package/search/flowr-search-printer.js +85 -0
  61. package/search/flowr-search-traverse.d.ts +7 -0
  62. package/search/flowr-search-traverse.js +12 -0
  63. package/search/flowr-search.d.ts +58 -0
  64. package/search/flowr-search.js +29 -0
  65. package/search/search-executor/search-generators.d.ts +37 -0
  66. package/search/search-executor/search-generators.js +64 -0
  67. package/search/search-executor/search-transformer.d.ts +57 -0
  68. package/search/search-executor/search-transformer.js +99 -0
  69. package/search/search-optimizer/search-optimizer.d.ts +9 -0
  70. package/search/search-optimizer/search-optimizer.js +89 -0
  71. package/util/arrays.d.ts +13 -0
  72. package/util/assert.d.ts +1 -1
  73. package/util/mermaid/mermaid.js +17 -0
  74. package/util/version.js +1 -1
@@ -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
@@ -0,0 +1,74 @@
1
+ import { RType } from '../r-bridge/lang-4.x/ast/model/type';
2
+ import type { VertexType } from '../dataflow/graph/vertex';
3
+ import type { NormalizedAst, ParentInformation } from '../r-bridge/lang-4.x/ast/model/processing/decorate';
4
+ import type { DataflowInformation } from '../dataflow/info';
5
+ import type { RNode } from '../r-bridge/lang-4.x/ast/model/model';
6
+ export type FlowrFilterName = keyof typeof FlowrFilters;
7
+ export declare enum FlowrFilter {
8
+ DropEmptyArguments = "drop-empty-arguments"
9
+ }
10
+ export declare const ValidFlowrFilters: Set<string>;
11
+ export declare const ValidFlowrFiltersReverse: {
12
+ [k: string]: string;
13
+ };
14
+ export declare const FlowrFilters: {
15
+ readonly "drop-empty-arguments": (n: RNode<ParentInformation>) => boolean;
16
+ };
17
+ type ValidFilterTypes = FlowrFilterName | RType | VertexType;
18
+ /**
19
+ * By default, we provide filter for every {@link RType} and {@link VertexType}.
20
+ */
21
+ export type FlowrFilterExpression = FlowrFilterCombinator | ValidFilterTypes;
22
+ interface BooleanBinaryNode<Composite> {
23
+ readonly type: 'and' | 'or' | 'xor';
24
+ readonly left: Composite;
25
+ readonly right: Composite;
26
+ }
27
+ interface BooleanUnaryNode<Composite> {
28
+ readonly type: 'not';
29
+ readonly operand: Composite;
30
+ }
31
+ type LeafRType = {
32
+ readonly type: 'r-type';
33
+ readonly value: RType;
34
+ };
35
+ type LeafVertexType = {
36
+ readonly type: 'vertex-type';
37
+ readonly value: VertexType;
38
+ };
39
+ type LeafSpecial = {
40
+ readonly type: 'special';
41
+ readonly value: string;
42
+ };
43
+ type Leaf = LeafRType | LeafVertexType | LeafSpecial;
44
+ type BooleanNode = BooleanBinaryNode<BooleanNode> | BooleanUnaryNode<BooleanNode> | Leaf;
45
+ type BooleanNodeOrCombinator = BooleanNode | FlowrFilterCombinator;
46
+ /**
47
+ * @see {@link FlowrFilterCombinator.is}
48
+ * @see {@link evalFilter}
49
+ * @see {@link binaryTreeToString}
50
+ */
51
+ export declare class FlowrFilterCombinator {
52
+ private tree;
53
+ protected constructor(init: BooleanNodeOrCombinator);
54
+ static is(value: BooleanNodeOrCombinator | ValidFilterTypes): FlowrFilterCombinator;
55
+ and(right: BooleanNodeOrCombinator | ValidFilterTypes): this;
56
+ or(right: BooleanNodeOrCombinator | ValidFilterTypes): this;
57
+ xor(right: BooleanNodeOrCombinator | ValidFilterTypes): this;
58
+ private binaryRight;
59
+ not(): this;
60
+ private unary;
61
+ private unpack;
62
+ get(): BooleanNode;
63
+ }
64
+ export declare function binaryTreeToString(tree: BooleanNode): string;
65
+ export declare function isBinaryTree(tree: unknown): tree is {
66
+ tree: BooleanNode;
67
+ };
68
+ interface FilterData {
69
+ readonly node: RNode<ParentInformation>;
70
+ readonly normalize: NormalizedAst;
71
+ readonly dataflow: DataflowInformation;
72
+ }
73
+ export declare function evalFilter(filter: FlowrFilterExpression, data: FilterData): boolean;
74
+ export {};
@@ -0,0 +1,136 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FlowrFilterCombinator = exports.FlowrFilters = exports.ValidFlowrFiltersReverse = exports.ValidFlowrFilters = exports.FlowrFilter = void 0;
4
+ exports.binaryTreeToString = binaryTreeToString;
5
+ exports.isBinaryTree = isBinaryTree;
6
+ exports.evalFilter = evalFilter;
7
+ const type_1 = require("../r-bridge/lang-4.x/ast/model/type");
8
+ const vertex_1 = require("../dataflow/graph/vertex");
9
+ var FlowrFilter;
10
+ (function (FlowrFilter) {
11
+ FlowrFilter["DropEmptyArguments"] = "drop-empty-arguments";
12
+ })(FlowrFilter || (exports.FlowrFilter = FlowrFilter = {}));
13
+ exports.ValidFlowrFilters = new Set(Object.values(FlowrFilter));
14
+ exports.ValidFlowrFiltersReverse = Object.fromEntries(Object.entries(FlowrFilter).map(([k, v]) => [v, k]));
15
+ exports.FlowrFilters = {
16
+ [FlowrFilter.DropEmptyArguments]: (n) => {
17
+ return n.type !== type_1.RType.Argument || n.name !== undefined;
18
+ }
19
+ };
20
+ /**
21
+ * @see {@link FlowrFilterCombinator.is}
22
+ * @see {@link evalFilter}
23
+ * @see {@link binaryTreeToString}
24
+ */
25
+ class FlowrFilterCombinator {
26
+ tree;
27
+ constructor(init) {
28
+ this.tree = this.unpack(init);
29
+ }
30
+ static is(value) {
31
+ if (typeof value === 'object') {
32
+ return new this(value);
33
+ }
34
+ else if (type_1.ValidRTypes.has(value)) {
35
+ return new this({ type: 'r-type', value: value });
36
+ }
37
+ else if (vertex_1.ValidVertexTypes.has(value)) {
38
+ return new this({ type: 'vertex-type', value: value });
39
+ }
40
+ else if (exports.ValidFlowrFilters.has(value)) {
41
+ return new this({ type: 'special', value: value });
42
+ }
43
+ else {
44
+ throw new Error(`Invalid filter value: ${value}`);
45
+ }
46
+ }
47
+ and(right) {
48
+ return this.binaryRight('and', right);
49
+ }
50
+ or(right) {
51
+ return this.binaryRight('or', right);
52
+ }
53
+ xor(right) {
54
+ return this.binaryRight('xor', right);
55
+ }
56
+ binaryRight(op, right) {
57
+ this.tree = {
58
+ type: op,
59
+ left: this.tree,
60
+ right: this.unpack(FlowrFilterCombinator.is(right))
61
+ };
62
+ return this;
63
+ }
64
+ not() {
65
+ return this.unary('not');
66
+ }
67
+ unary(op) {
68
+ this.tree = {
69
+ type: op,
70
+ operand: this.tree
71
+ };
72
+ return this;
73
+ }
74
+ unpack(val) {
75
+ return val instanceof FlowrFilterCombinator ? val.tree : val;
76
+ }
77
+ get() {
78
+ return this.tree;
79
+ }
80
+ }
81
+ exports.FlowrFilterCombinator = FlowrFilterCombinator;
82
+ function binaryTreeToString(tree) {
83
+ const res = treeToStringImpl(tree, 0);
84
+ // drop outer parens
85
+ if (res.startsWith('(') && res.endsWith(')')) {
86
+ return res.slice(1, -1);
87
+ }
88
+ else {
89
+ return res;
90
+ }
91
+ }
92
+ const typeToSymbol = {
93
+ 'and': '∧',
94
+ 'or': '∨',
95
+ 'xor': '⊕',
96
+ 'not': '¬'
97
+ };
98
+ function treeToStringImpl(tree, depth) {
99
+ if (tree.type === 'r-type' || tree.type === 'vertex-type' || tree.type === 'special') {
100
+ return tree.value;
101
+ }
102
+ if (tree.type === 'not') {
103
+ return `${typeToSymbol[tree.type]}${treeToStringImpl(tree.operand, depth)}`;
104
+ }
105
+ const left = treeToStringImpl(tree.left, depth + 1);
106
+ const right = treeToStringImpl(tree.right, depth + 1);
107
+ return `(${left} ${typeToSymbol[tree.type]} ${right})`;
108
+ }
109
+ function isBinaryTree(tree) {
110
+ return typeof tree === 'object' && tree !== null && 'tree' in tree;
111
+ }
112
+ const evalVisit = {
113
+ and: ({ left, right }, data) => evalTree(left, data) && evalTree(right, data),
114
+ or: ({ left, right }, data) => evalTree(left, data) || evalTree(right, data),
115
+ xor: ({ left, right }, data) => evalTree(left, data) !== evalTree(right, data),
116
+ 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];
121
+ if (getHandler) {
122
+ return getHandler(node);
123
+ }
124
+ throw new Error(`Special filter not implemented: ${value}`);
125
+ }
126
+ };
127
+ function evalTree(tree, data) {
128
+ /* we ensure that the types fit */
129
+ return evalVisit[tree.type](tree, data);
130
+ }
131
+ function evalFilter(filter, data) {
132
+ /* common lift, this can be improved easily :D */
133
+ const tree = FlowrFilterCombinator.is(filter);
134
+ return evalTree(tree.get(), data);
135
+ }
136
+ //# sourceMappingURL=flowr-search-filters.js.map
@@ -0,0 +1,10 @@
1
+ import type { FlowrSearchLike } from './flowr-search-builder';
2
+ export interface FlowrSearchMermaidBuilderOptions {
3
+ header?: string;
4
+ }
5
+ /**
6
+ * Converts a {@link FlowrSearchLike} object to a mermaid flowchart.
7
+ */
8
+ export declare function flowrSearchToMermaid(search: FlowrSearchLike, conf?: FlowrSearchMermaidBuilderOptions): string;
9
+ export declare function flowrSearchToAscii(search: FlowrSearchLike): string;
10
+ export declare function flowrSearchToCode(search: FlowrSearchLike): string;
@@ -0,0 +1,85 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.flowrSearchToMermaid = flowrSearchToMermaid;
4
+ exports.flowrSearchToAscii = flowrSearchToAscii;
5
+ exports.flowrSearchToCode = flowrSearchToCode;
6
+ const flowr_search_traverse_1 = require("./flowr-search-traverse");
7
+ const mermaid_1 = require("../util/mermaid/mermaid");
8
+ const flowr_search_filters_1 = require("./flowr-search-filters");
9
+ const vertex_1 = require("../dataflow/graph/vertex");
10
+ const type_1 = require("../r-bridge/lang-4.x/ast/model/type");
11
+ /**
12
+ * Converts a {@link FlowrSearchLike} object to a mermaid flowchart.
13
+ */
14
+ function flowrSearchToMermaid(search, conf) {
15
+ const out = [conf?.header ?? 'flowchart LR'];
16
+ let count = 0;
17
+ out.push((0, flowr_search_traverse_1.traverseFlowrSearchBuilderType)(search, ({ type, name, args }) => `${count}("<b>${name}</b>(${argsToMermaidString(args)})<br/>_${type}_")`, (acc, { name, args, type }) => `${acc} --> ${++count}["<b>${name}</b>(${argsToMermaidString(args)})<br/>_${type}_"]`));
18
+ return out.join('\n');
19
+ }
20
+ function argsToMermaidString(args) {
21
+ if (args === undefined) {
22
+ return '';
23
+ }
24
+ return Object.entries(args).map(([key, value]) => `${key}: ${(0, flowr_search_filters_1.isBinaryTree)(value) ? '_' + (0, mermaid_1.escapeMarkdown)((0, flowr_search_filters_1.binaryTreeToString)(value.tree)) + '_'
25
+ : (0, mermaid_1.escapeMarkdown)(JSON.stringify(value))}`)
26
+ .join(', ');
27
+ }
28
+ function argsToAsciiString(args) {
29
+ if (args === undefined) {
30
+ return '';
31
+ }
32
+ else if (Object.keys(args).length === 1) {
33
+ const key = Object.keys(args)[0];
34
+ const value = args[key];
35
+ return `${key}: ${(0, flowr_search_filters_1.isBinaryTree)(value) ? '_' + (0, flowr_search_filters_1.binaryTreeToString)(value.tree) + '_' : JSON.stringify(value)}`;
36
+ }
37
+ return Object.entries(args).map(([key, value]) => `${key}: ${(0, flowr_search_filters_1.isBinaryTree)(value) ? '_' + (0, flowr_search_filters_1.binaryTreeToString)(value.tree) + '_' : JSON.stringify(value)}`)
38
+ .join(', ');
39
+ }
40
+ function flowrSearchToAscii(search) {
41
+ return (0, flowr_search_traverse_1.traverseFlowrSearchBuilderType)(search, ({ name, args }) => `${name}(${argsToAsciiString(args)})`, (acc, { name, args }) => `${acc} --> ${name}(${argsToAsciiString(args)})`);
42
+ }
43
+ function argsToCodeString(args) {
44
+ if (args === undefined) {
45
+ return '';
46
+ }
47
+ return Object.entries(args).map(([, value]) => `${JSON.stringify(value)}`)
48
+ .join(', ');
49
+ }
50
+ function flowrSearchToCode(search) {
51
+ return (0, flowr_search_traverse_1.traverseFlowrSearchBuilderType)(search, (node) => `Q.${flowrGeneratorToCode(node)}`, (acc, node) => `${acc}.${flowrTransformerToCode(node)}`);
52
+ }
53
+ function flowrTransformerToCode(node) {
54
+ if (node.name === 'filter') {
55
+ const a = node.args.filter;
56
+ if (vertex_1.ValidVertexTypes.has(String(a))) {
57
+ return `${node.name}(VertexType.${vertex_1.ValidVertexTypeReverse[String(a)]})`;
58
+ }
59
+ else if (type_1.ValidRTypes.has(String(a))) {
60
+ return `${node.name}(RType.${type_1.ValidRTypesReverse[String(a)]})`;
61
+ }
62
+ else if (flowr_search_filters_1.ValidFlowrFilters.has(String(a))) {
63
+ return `${node.name}(FlowrFilter.${flowr_search_filters_1.ValidFlowrFiltersReverse[String(a)]})`;
64
+ }
65
+ }
66
+ return `${node.name}(${argsToCodeString(node.args)})`;
67
+ }
68
+ function flowrGeneratorToCode(node) {
69
+ if (node.name !== 'get') {
70
+ return `${node.name}(${argsToCodeString(node.args)})`;
71
+ }
72
+ const a = node.args.filter;
73
+ if (Object.keys(a).length === 1) {
74
+ if (a.name) {
75
+ return `var(${JSON.stringify(a.name)})`;
76
+ }
77
+ }
78
+ else if (Object.keys(a).length === 2) {
79
+ if (a.name && a.line) {
80
+ return `varInLine(${JSON.stringify(a.name)}, ${JSON.stringify(a.line)})`;
81
+ }
82
+ }
83
+ return `${node.name}(${argsToCodeString(node.args)})`;
84
+ }
85
+ //# sourceMappingURL=flowr-search-printer.js.map
@@ -0,0 +1,7 @@
1
+ import type { FlowrSearchLike } from './flowr-search-builder';
2
+ import type { FlowrSearchGeneratorNode } from './search-executor/search-generators';
3
+ import type { FlowrSearchTransformerNode } from './search-executor/search-transformer';
4
+ /**
5
+ * Allows you to traverse a {@link FlowrSearchLike} object.
6
+ */
7
+ export declare function traverseFlowrSearchBuilderType<Accumulate, GeneratorVisit extends (generator: FlowrSearchGeneratorNode) => Accumulate, TransformerVisit extends (acc: Accumulate, transformer: FlowrSearchTransformerNode) => Accumulate>(search: FlowrSearchLike, gen: GeneratorVisit, trans: TransformerVisit): Accumulate;
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.traverseFlowrSearchBuilderType = traverseFlowrSearchBuilderType;
4
+ const flowr_search_builder_1 = require("./flowr-search-builder");
5
+ /**
6
+ * Allows you to traverse a {@link FlowrSearchLike} object.
7
+ */
8
+ function traverseFlowrSearchBuilderType(search, gen, trans) {
9
+ const s = (0, flowr_search_builder_1.getFlowrSearch)(search);
10
+ return s.search.reduce(trans, gen(s.generator));
11
+ }
12
+ //# sourceMappingURL=flowr-search-traverse.js.map
@@ -0,0 +1,58 @@
1
+ import type { NoInfo, RNode } from '../r-bridge/lang-4.x/ast/model/model';
2
+ import type { Pipeline, PipelineOutput, PipelineStepOutputWithName } from '../core/steps/pipeline/pipeline';
3
+ import type { NormalizedAst } from '../r-bridge/lang-4.x/ast/model/processing/decorate';
4
+ import type { NodeId } from '../r-bridge/lang-4.x/ast/model/processing/node-id';
5
+ import type { DataflowInformation } from '../dataflow/info';
6
+ /**
7
+ * Yes, for now we do technically not need a wrapper around the RNode, but this allows us to attach caches etc.
8
+ * just for the respective search.
9
+ */
10
+ export interface FlowrSearchElement<Info> {
11
+ readonly node: RNode<Info>;
12
+ }
13
+ export interface FlowrSearchNodeBase<Type extends string, Name extends string, Args extends Record<string, unknown> | undefined> {
14
+ readonly type: Type;
15
+ readonly name: Name;
16
+ readonly args: Args;
17
+ }
18
+ export type FlowrSearchGeneratorNodeBase<Name extends string, Args extends Record<string, unknown> | undefined> = FlowrSearchNodeBase<'generator', Name, Args>;
19
+ export type FlowrSearchTransformerNodeBase<Name extends string, Args extends Record<string, unknown> | undefined> = FlowrSearchNodeBase<'transformer', Name, Args>;
20
+ export interface FlowrSearchGetFilter extends Record<string, unknown> {
21
+ /**
22
+ * The node must be in the given line.
23
+ */
24
+ readonly line?: number;
25
+ /**
26
+ * The node must be in the given column.
27
+ */
28
+ readonly column?: number;
29
+ /**
30
+ * The node must have the given name.
31
+ * To treat this name as a regular expression, set {@link FlowrSearchGetFilter#nameIsRegex} to true.
32
+ */
33
+ readonly name?: string;
34
+ /**
35
+ * Only useful in combination with `name`. If true, the name is treated as a regular expression.
36
+ */
37
+ readonly nameIsRegex?: boolean;
38
+ /**
39
+ * The node must have the given id.
40
+ */
41
+ readonly id?: NodeId;
42
+ }
43
+ type MinimumInputForFlowrSearch<P extends Pipeline> = PipelineStepOutputWithName<P, 'normalize'> extends NormalizedAst ? (PipelineStepOutputWithName<P, 'dataflow'> extends DataflowInformation ? PipelineOutput<P> & {
44
+ normalize: NormalizedAst;
45
+ dataflow: DataflowInformation;
46
+ } : never) : never;
47
+ /** we allow any pipeline, which provides us with a 'normalize' and 'dataflow' step */
48
+ export type FlowrSearchInput<P extends Pipeline> = MinimumInputForFlowrSearch<P>;
49
+ /** Intentionally, we abstract away from an array to avoid the use of conventional typescript operations */
50
+ export declare class FlowrSearchElements<Info = NoInfo, Elements extends FlowrSearchElement<Info>[] = FlowrSearchElement<Info>[]> {
51
+ private elements;
52
+ constructor(elements?: Elements);
53
+ add(element: FlowrSearchElement<Info>): this;
54
+ addAll(elements: FlowrSearchElement<Info>[]): this;
55
+ getElements(): readonly FlowrSearchElement<Info>[];
56
+ mutate<OutElements extends Elements>(mutator: (elements: Elements) => OutElements): this;
57
+ }
58
+ export {};
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FlowrSearchElements = void 0;
4
+ /** Intentionally, we abstract away from an array to avoid the use of conventional typescript operations */
5
+ class FlowrSearchElements {
6
+ elements = [];
7
+ constructor(elements) {
8
+ if (elements) {
9
+ this.elements = elements;
10
+ }
11
+ }
12
+ add(element) {
13
+ this.elements.push(element);
14
+ return this;
15
+ }
16
+ addAll(elements) {
17
+ this.elements.push(...elements);
18
+ return this;
19
+ }
20
+ getElements() {
21
+ return this.elements;
22
+ }
23
+ mutate(mutator) {
24
+ this.elements = mutator(this.elements);
25
+ return this;
26
+ }
27
+ }
28
+ exports.FlowrSearchElements = FlowrSearchElements;
29
+ //# sourceMappingURL=flowr-search.js.map
@@ -0,0 +1,37 @@
1
+ import type { FlowrSearchElement, FlowrSearchGeneratorNodeBase, FlowrSearchGetFilter, FlowrSearchInput } from '../flowr-search';
2
+ import { FlowrSearchElements } from '../flowr-search';
3
+ import type { Pipeline } from '../../core/steps/pipeline/pipeline';
4
+ import type { TailTypesOrUndefined } from '../../util/arrays';
5
+ import type { ParentInformation } from '../../r-bridge/lang-4.x/ast/model/processing/decorate';
6
+ import type { SlicingCriteria } from '../../slicing/criterion/parse';
7
+ /**
8
+ * This is a union of all possible generator node types
9
+ */
10
+ export type FlowrSearchGeneratorNode = {
11
+ [K in GeneratorNames]: FlowrSearchGeneratorNodeBase<K, TailTypesOrUndefined<Parameters<typeof generators[K]>>>;
12
+ }[GeneratorNames];
13
+ export type GeneratorNames = keyof typeof generators;
14
+ export type GetGenerator<Name extends GeneratorNames> = FlowrSearchGeneratorNode & {
15
+ name: Name;
16
+ };
17
+ /**
18
+ * All supported generators!
19
+ */
20
+ export declare const generators: {
21
+ readonly all: typeof generateAll;
22
+ readonly get: typeof generateGet;
23
+ readonly criterion: typeof generateCriterion;
24
+ readonly from: typeof generateFrom;
25
+ };
26
+ declare function generateAll(data: FlowrSearchInput<Pipeline>): FlowrSearchElements<ParentInformation>;
27
+ declare function generateGet(data: FlowrSearchInput<Pipeline>, { filter: { line, column, id, name, nameIsRegex } }: {
28
+ filter: FlowrSearchGetFilter;
29
+ }): FlowrSearchElements<ParentInformation>;
30
+ declare function generateFrom(data: FlowrSearchInput<Pipeline>, args: {
31
+ from: FlowrSearchElement<ParentInformation> | FlowrSearchElement<ParentInformation>[];
32
+ }): FlowrSearchElements<ParentInformation>;
33
+ declare function generateCriterion(data: FlowrSearchInput<Pipeline>, args: {
34
+ criterion: SlicingCriteria;
35
+ }): FlowrSearchElements<ParentInformation>;
36
+ export declare function getGenerator<Name extends GeneratorNames>(name: Name): typeof generators[Name];
37
+ export {};