@eagleoutice/flowr 2.1.11 → 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 (62) hide show
  1. package/README.md +1 -0
  2. package/cli/repl/commands/repl-query.js +1 -1
  3. package/cli/repl/server/connection.js +1 -1
  4. package/core/steps/pipeline/default-pipelines.d.ts +6 -0
  5. package/core/steps/pipeline/default-pipelines.js +6 -0
  6. package/dataflow/graph/vertex.d.ts +4 -0
  7. package/dataflow/graph/vertex.js +3 -1
  8. package/documentation/doc-util/doc-dfg.js +1 -1
  9. package/documentation/doc-util/doc-query.js +1 -1
  10. package/documentation/doc-util/doc-search.d.ts +25 -0
  11. package/documentation/doc-util/doc-search.js +121 -0
  12. package/documentation/doc-util/doc-types.d.ts +10 -2
  13. package/documentation/doc-util/doc-types.js +81 -3
  14. package/documentation/print-dataflow-graph-wiki.js +1 -1
  15. package/documentation/print-interface-wiki.js +24 -13
  16. package/documentation/print-normalized-ast-wiki.js +4 -4
  17. package/documentation/print-query-wiki.js +22 -0
  18. package/documentation/print-search-wiki.d.ts +1 -0
  19. package/documentation/print-search-wiki.js +74 -0
  20. package/package.json +2 -1
  21. package/queries/base-query-format.d.ts +2 -2
  22. package/queries/catalog/call-context-query/call-context-query-executor.d.ts +1 -1
  23. package/queries/catalog/call-context-query/call-context-query-executor.js +1 -1
  24. package/queries/catalog/cluster-query/cluster-query-executor.d.ts +1 -1
  25. package/queries/catalog/cluster-query/cluster-query-executor.js +1 -1
  26. package/queries/catalog/dataflow-query/dataflow-query-executor.d.ts +1 -1
  27. package/queries/catalog/dataflow-query/dataflow-query-executor.js +1 -1
  28. package/queries/catalog/dependencies-query/dependencies-query-executor.js +2 -2
  29. package/queries/catalog/lineage-query/lineage-query-executor.d.ts +1 -1
  30. package/queries/catalog/lineage-query/lineage-query-executor.js +1 -1
  31. package/queries/catalog/search-query/search-query-executor.d.ts +3 -0
  32. package/queries/catalog/search-query/search-query-executor.js +27 -0
  33. package/queries/catalog/search-query/search-query-format.d.ts +72 -0
  34. package/queries/catalog/search-query/search-query-format.js +29 -0
  35. package/queries/catalog/static-slice-query/static-slice-query-executor.d.ts +1 -1
  36. package/queries/catalog/static-slice-query/static-slice-query-executor.js +1 -1
  37. package/queries/query.d.ts +59 -1
  38. package/queries/query.js +3 -1
  39. package/r-bridge/lang-4.x/ast/model/type.d.ts +4 -0
  40. package/r-bridge/lang-4.x/ast/model/type.js +3 -1
  41. package/search/flowr-search-builder.d.ts +193 -0
  42. package/search/flowr-search-builder.js +192 -0
  43. package/search/flowr-search-executor.d.ts +9 -0
  44. package/search/flowr-search-executor.js +16 -0
  45. package/search/flowr-search-filters.d.ts +74 -0
  46. package/search/flowr-search-filters.js +136 -0
  47. package/search/flowr-search-printer.d.ts +10 -0
  48. package/search/flowr-search-printer.js +85 -0
  49. package/search/flowr-search-traverse.d.ts +7 -0
  50. package/search/flowr-search-traverse.js +12 -0
  51. package/search/flowr-search.d.ts +58 -0
  52. package/search/flowr-search.js +29 -0
  53. package/search/search-executor/search-generators.d.ts +37 -0
  54. package/search/search-executor/search-generators.js +64 -0
  55. package/search/search-executor/search-transformer.d.ts +57 -0
  56. package/search/search-executor/search-transformer.js +99 -0
  57. package/search/search-optimizer/search-optimizer.d.ts +9 -0
  58. package/search/search-optimizer/search-optimizer.js +89 -0
  59. package/util/arrays.d.ts +13 -0
  60. package/util/assert.d.ts +1 -1
  61. package/util/mermaid/mermaid.js +17 -0
  62. package/util/version.js +1 -1
package/README.md CHANGED
@@ -73,3 +73,4 @@ We welcome every contribution! Please check out the [contributing guidelines](ht
73
73
  [GPLv3 License](LICENSE).
74
74
 
75
75
  ----
76
+ # abstract-interpretation-ltx
@@ -61,7 +61,7 @@ async function processQueryArgs(line, shell, output) {
61
61
  }
62
62
  const processed = await getDataflow(shell, args.join(' '));
63
63
  return {
64
- query: (0, query_1.executeQueries)({ graph: processed.dataflow.graph, ast: processed.normalize }, parsedQuery),
64
+ query: (0, query_1.executeQueries)({ dataflow: processed.dataflow, ast: processed.normalize }, parsedQuery),
65
65
  processed
66
66
  };
67
67
  }
@@ -326,7 +326,7 @@ class FlowRServerConnection {
326
326
  const { dataflow: dfg, normalize: ast } = fileInformation.pipeline.getResults(true);
327
327
  (0, assert_1.guard)(dfg !== undefined, `Dataflow graph must be present (request: ${request.filetoken})`);
328
328
  (0, assert_1.guard)(ast !== undefined, `AST must be present (request: ${request.filetoken})`);
329
- const results = (0, query_1.executeQueries)({ graph: dfg.graph, ast }, request.query);
329
+ const results = (0, query_1.executeQueries)({ dataflow: dfg, ast }, request.query);
330
330
  (0, send_1.sendMessage)(this.socket, {
331
331
  type: 'response-query',
332
332
  id: request.id,
@@ -227,6 +227,11 @@ export declare const DEFAULT_SLICE_WITHOUT_RECONSTRUCT_PIPELINE: import("./pipel
227
227
  readonly dependencies: readonly ["dataflow"];
228
228
  readonly requiredInput: import("../all/static-slicing/00-slice").SliceRequiredInput;
229
229
  }>;
230
+ /**
231
+ * The default pipeline for working with flowr, including the dataflow step,
232
+ * see the {@link DEFAULT_NORMALIZE_PIPELINE} for the pipeline without the dataflow step,
233
+ * and the {@link DEFAULT_SLICE_AND_RECONSTRUCT_PIPELINE} for the pipeline with slicing and reconstructing steps
234
+ */
230
235
  export declare const DEFAULT_DATAFLOW_PIPELINE: import("./pipeline").Pipeline<{
231
236
  readonly name: "parse";
232
237
  readonly humanReadableName: "parse with R shell";
@@ -280,6 +285,7 @@ export declare const DEFAULT_DATAFLOW_PIPELINE: import("./pipeline").Pipeline<{
280
285
  };
281
286
  readonly dependencies: readonly ["normalize"];
282
287
  }>;
288
+ /** The pipeline to use when you want to parse and normalize your R file, see {@link DEFAULT_DATAFLOW_PIPELINE} for the additional `dataflow` step */
283
289
  export declare const DEFAULT_NORMALIZE_PIPELINE: import("./pipeline").Pipeline<{
284
290
  readonly name: "parse";
285
291
  readonly humanReadableName: "parse with R shell";
@@ -13,7 +13,13 @@ const _10_reconstruct_1 = require("../all/static-slicing/10-reconstruct");
13
13
  exports.DEFAULT_SLICING_PIPELINE = (0, pipeline_1.createPipeline)(_00_parse_1.PARSE_WITH_R_SHELL_STEP, _10_normalize_1.NORMALIZE, _20_dataflow_1.STATIC_DATAFLOW, _00_slice_1.STATIC_SLICE, _10_reconstruct_1.NAIVE_RECONSTRUCT);
14
14
  exports.DEFAULT_SLICE_AND_RECONSTRUCT_PIPELINE = exports.DEFAULT_SLICING_PIPELINE;
15
15
  exports.DEFAULT_SLICE_WITHOUT_RECONSTRUCT_PIPELINE = (0, pipeline_1.createPipeline)(_00_parse_1.PARSE_WITH_R_SHELL_STEP, _10_normalize_1.NORMALIZE, _20_dataflow_1.STATIC_DATAFLOW, _00_slice_1.STATIC_SLICE);
16
+ /**
17
+ * The default pipeline for working with flowr, including the dataflow step,
18
+ * see the {@link DEFAULT_NORMALIZE_PIPELINE} for the pipeline without the dataflow step,
19
+ * and the {@link DEFAULT_SLICE_AND_RECONSTRUCT_PIPELINE} for the pipeline with slicing and reconstructing steps
20
+ */
16
21
  exports.DEFAULT_DATAFLOW_PIPELINE = (0, pipeline_1.createPipeline)(_00_parse_1.PARSE_WITH_R_SHELL_STEP, _10_normalize_1.NORMALIZE, _20_dataflow_1.STATIC_DATAFLOW);
22
+ /** The pipeline to use when you want to parse and normalize your R file, see {@link DEFAULT_DATAFLOW_PIPELINE} for the additional `dataflow` step */
17
23
  exports.DEFAULT_NORMALIZE_PIPELINE = (0, pipeline_1.createPipeline)(_00_parse_1.PARSE_WITH_R_SHELL_STEP, _10_normalize_1.NORMALIZE);
18
24
  exports.DEFAULT_PARSE_PIPELINE = (0, pipeline_1.createPipeline)(_00_parse_1.PARSE_WITH_R_SHELL_STEP);
19
25
  //# sourceMappingURL=default-pipelines.js.map
@@ -10,6 +10,10 @@ export declare enum VertexType {
10
10
  VariableDefinition = "variable-definition",
11
11
  FunctionDefinition = "function-definition"
12
12
  }
13
+ export declare const ValidVertexTypes: Set<string>;
14
+ export declare const ValidVertexTypeReverse: {
15
+ [k: string]: string;
16
+ };
13
17
  /**
14
18
  * A single index of a container, which is not a container itself.
15
19
  *
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.VertexType = void 0;
3
+ exports.ValidVertexTypeReverse = exports.ValidVertexTypes = exports.VertexType = void 0;
4
4
  exports.isParentContainerIndex = isParentContainerIndex;
5
5
  exports.isValueVertex = isValueVertex;
6
6
  exports.isUseVertex = isUseVertex;
@@ -15,6 +15,8 @@ var VertexType;
15
15
  VertexType["VariableDefinition"] = "variable-definition";
16
16
  VertexType["FunctionDefinition"] = "function-definition";
17
17
  })(VertexType || (exports.VertexType = VertexType = {}));
18
+ exports.ValidVertexTypes = new Set(Object.values(VertexType));
19
+ exports.ValidVertexTypeReverse = Object.fromEntries(Object.entries(VertexType).map(([k, v]) => [v, k]));
18
20
  function isParentContainerIndex(index) {
19
21
  return 'subIndices' in index;
20
22
  }
@@ -42,7 +42,7 @@ async function printDfGraphForCode(shell, code, { mark, showCode = true, codeOpe
42
42
  if (switchCodeAndGraph) {
43
43
  (0, assert_1.guard)(showCode, 'can not switch code and graph if code is not shown');
44
44
  }
45
- const metaInfo = `The analysis required _${(0, time_1.printAsMs)(duration)}_ (incl. parse and normalize) within the generation environment.`;
45
+ const metaInfo = `The analysis required _${(0, time_1.printAsMs)(duration)}_ (including parse and normalize) within the generation environment.`;
46
46
  const dfGraph = printDfGraph(result.dataflow.graph, mark);
47
47
  let resultText = '\n\n';
48
48
  if (showCode) {
@@ -23,7 +23,7 @@ async function showQuery(shell, code, queries, { showCode, collapseResult, colla
23
23
  shell,
24
24
  request: (0, retriever_1.requestFromInput)(code)
25
25
  }).allRemainingSteps();
26
- const results = (0, query_1.executeQueries)({ graph: analysis.dataflow.graph, ast: analysis.normalize }, queries);
26
+ const results = (0, query_1.executeQueries)({ dataflow: analysis.dataflow, ast: analysis.normalize }, queries);
27
27
  const duration = performance.now() - now;
28
28
  const metaInfo = `
29
29
  The analysis required _${(0, time_1.printAsMs)(duration)}_ (including parsing and normalization and the query) within the generation environment.
@@ -0,0 +1,25 @@
1
+ import type { RShell } from '../../r-bridge/shell';
2
+ import type { SupportedQueryTypes } from '../../queries/query';
3
+ import type { SupportedVirtualQueryTypes } from '../../queries/virtual-query/virtual-queries';
4
+ import type { FlowrSearchLike } from '../../search/flowr-search-builder';
5
+ export interface ShowSearchOptions {
6
+ readonly showCode?: boolean;
7
+ readonly collapseResult?: boolean;
8
+ }
9
+ export declare function showSearch(shell: RShell, code: string, search: FlowrSearchLike, { collapseResult }?: ShowSearchOptions): Promise<string>;
10
+ export interface QueryDocumentation {
11
+ readonly name: string;
12
+ readonly type: 'virtual' | 'active';
13
+ readonly shortDescription: string;
14
+ readonly functionName: string;
15
+ readonly functionFile: string;
16
+ readonly buildExplanation: (shell: RShell) => Promise<string>;
17
+ }
18
+ export declare const RegisteredQueries: {
19
+ active: Map<string, QueryDocumentation>;
20
+ virtual: Map<string, QueryDocumentation>;
21
+ };
22
+ export declare function registerQueryDocumentation(query: SupportedQueryTypes | SupportedVirtualQueryTypes, doc: QueryDocumentation): void;
23
+ export declare function linkToQueryOfName(id: SupportedQueryTypes | SupportedVirtualQueryTypes): string;
24
+ export declare function tocForQueryType(type: 'active' | 'virtual'): string;
25
+ export declare function explainQueries(shell: RShell, type: 'active' | 'virtual'): Promise<string>;
@@ -0,0 +1,121 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RegisteredQueries = void 0;
4
+ exports.showSearch = showSearch;
5
+ exports.registerQueryDocumentation = registerQueryDocumentation;
6
+ exports.linkToQueryOfName = linkToQueryOfName;
7
+ exports.tocForQueryType = tocForQueryType;
8
+ exports.explainQueries = explainQueries;
9
+ const pipeline_executor_1 = require("../../core/pipeline-executor");
10
+ const default_pipelines_1 = require("../../core/steps/pipeline/default-pipelines");
11
+ const retriever_1 = require("../../r-bridge/retriever");
12
+ const doc_files_1 = require("./doc-files");
13
+ const doc_dfg_1 = require("./doc-dfg");
14
+ const doc_code_1 = require("./doc-code");
15
+ const time_1 = require("../../util/time");
16
+ const flowr_search_executor_1 = require("../../search/flowr-search-executor");
17
+ const flowr_search_printer_1 = require("../../search/flowr-search-printer");
18
+ const node_id_1 = require("../../r-bridge/lang-4.x/ast/model/processing/node-id");
19
+ const dfg_1 = require("../../util/mermaid/dfg");
20
+ async function showSearch(shell, code, search, { collapseResult = true } = {}) {
21
+ const now = performance.now();
22
+ const analysis = await new pipeline_executor_1.PipelineExecutor(default_pipelines_1.DEFAULT_DATAFLOW_PIPELINE, {
23
+ shell,
24
+ request: (0, retriever_1.requestFromInput)(code)
25
+ }).allRemainingSteps();
26
+ const result = (0, flowr_search_executor_1.runSearch)(search, analysis);
27
+ const duration = performance.now() - now;
28
+ const metaInfo = `
29
+ The search required _${(0, time_1.printAsMs)(duration)}_ (including parsing and normalization and the query) within the generation environment.
30
+ `.trim();
31
+ return `
32
+
33
+ ${(0, doc_code_1.codeBlock)('ts', (0, flowr_search_printer_1.flowrSearchToCode)(search))}
34
+
35
+ <details style="color:gray"> <summary>Search Visualization</summary>
36
+
37
+ ${(0, doc_code_1.codeBlock)('mermaid', (0, flowr_search_printer_1.flowrSearchToMermaid)(search))}
38
+
39
+ In the code:
40
+
41
+ ${(0, doc_code_1.codeBlock)('r', code)}
42
+
43
+ <details style="color:gray"> <summary>JSON Representation</summary>
44
+
45
+ ${(0, doc_code_1.codeBlock)('json', JSON.stringify(search, null, 2))}
46
+
47
+ </details>
48
+
49
+ </details>
50
+
51
+
52
+ ${collapseResult ? ' <details> <summary style="color:gray">Show Results</summary>' : ''}
53
+
54
+ The query returns the following vetices (all references to \`x\` in the code):
55
+ ${result.map(({ node }) => `<b>${node.info.id} ('${(0, node_id_1.recoverContent)(node.info.id, analysis.dataflow.graph)}')</b> at L${(0, dfg_1.formatRange)(node.location)}`).join(', ')}
56
+
57
+ ${metaInfo}
58
+
59
+ The returned results are highlighted thick and blue within the dataflow graph:
60
+
61
+ ${await (0, doc_dfg_1.printDfGraphForCode)(shell, code, { showCode: false, switchCodeAndGraph: false, mark: new Set(result.map(({ node }) => node.info.id)) })}
62
+
63
+
64
+ ${collapseResult ? '</details>' : ''}
65
+
66
+ `;
67
+ }
68
+ exports.RegisteredQueries = {
69
+ 'active': new Map(),
70
+ 'virtual': new Map()
71
+ };
72
+ function registerQueryDocumentation(query, doc) {
73
+ const map = exports.RegisteredQueries[doc.type];
74
+ if (map.has(query)) {
75
+ throw new Error(`Query ${query} already registered`);
76
+ }
77
+ map.set(query, doc);
78
+ }
79
+ function linkify(name) {
80
+ return name.toLowerCase().replace(/ /g, '-');
81
+ }
82
+ function linkToQueryOfName(id) {
83
+ const query = exports.RegisteredQueries.active.get(id) ?? exports.RegisteredQueries.virtual.get(id);
84
+ if (!query) {
85
+ throw new Error(`Query ${id} not found`);
86
+ }
87
+ return `[${query.name}](#${linkify(query.name)})`;
88
+ }
89
+ function tocForQueryType(type) {
90
+ const queries = [...exports.RegisteredQueries[type].entries()].sort(([, { name: a }], [, { name: b }]) => a.localeCompare(b));
91
+ const result = [];
92
+ for (const [id, { name, shortDescription }] of queries) {
93
+ result.push(`1. [${name}](#${linkify(name)}) (\`${id}\`):\\\n ${shortDescription}`);
94
+ }
95
+ return result.join('\n');
96
+ }
97
+ async function explainQuery(shell, { name, functionName, functionFile, buildExplanation }) {
98
+ return `
99
+ ### ${name}
100
+
101
+ ${await buildExplanation(shell)}
102
+
103
+ <details>
104
+
105
+ <summary style="color:gray">Implementation Details</summary>
106
+
107
+ Responsible for the execution of the ${name} query is \`${functionName}\` in ${(0, doc_files_1.getFilePathMd)(functionFile)}.
108
+
109
+ </details>
110
+
111
+ `;
112
+ }
113
+ async function explainQueries(shell, type) {
114
+ const queries = [...exports.RegisteredQueries[type].entries()].sort(([, { name: a }], [, { name: b }]) => a.localeCompare(b));
115
+ const result = [];
116
+ for (const [, doc] of queries) {
117
+ result.push(await explainQuery(shell, doc));
118
+ }
119
+ return result.join(`\n${'-'.repeat(5)}\n\n`);
120
+ }
121
+ //# sourceMappingURL=doc-search.js.map
@@ -2,7 +2,7 @@ import ts from 'typescript';
2
2
  export interface TypeElementInSource {
3
3
  name: string;
4
4
  node: ts.Node;
5
- kind: 'interface' | 'type' | 'enum' | 'class';
5
+ kind: 'interface' | 'type' | 'enum' | 'class' | 'variable';
6
6
  extends: string[];
7
7
  generics: string[];
8
8
  filePath: string;
@@ -25,7 +25,7 @@ export interface MermaidTypeReport {
25
25
  program: ts.Program;
26
26
  }
27
27
  export declare function getTypesFromFolderAsMermaid(options: GetTypesAsMermaidOption): MermaidTypeReport;
28
- export declare function implSnippet(node: TypeElementInSource | undefined, program: ts.Program, nesting?: number): string;
28
+ export declare function implSnippet(node: TypeElementInSource | undefined, program: ts.Program, showName?: boolean, nesting?: number): string;
29
29
  export interface PrintHierarchyArguments {
30
30
  readonly program: ts.Program;
31
31
  readonly hierarchy: TypeElementInSource[];
@@ -36,3 +36,11 @@ export interface PrintHierarchyArguments {
36
36
  }
37
37
  export declare const mermaidHide: string[];
38
38
  export declare function printHierarchy({ program, hierarchy, root, collapseFromNesting, initialNesting, maxDepth }: PrintHierarchyArguments): string;
39
+ /**
40
+ * Create a short link to a type in the documentation
41
+ * @param name - The name of the type, e.g. `MyType`, may include a container, e.g. `MyContainer::MyType` (this works with function nestings too)
42
+ * @param hierarchy - The hierarchy of types to search in
43
+ * @param codeStyle - Whether to use code style for the link
44
+ */
45
+ export declare function shortLink(name: string, hierarchy: TypeElementInSource[], codeStyle?: boolean): string;
46
+ export declare function getDocumentationForType(name: string, hierarchy: TypeElementInSource[]): string;
@@ -10,6 +10,8 @@ exports.getTypePathLink = getTypePathLink;
10
10
  exports.getTypesFromFolderAsMermaid = getTypesFromFolderAsMermaid;
11
11
  exports.implSnippet = implSnippet;
12
12
  exports.printHierarchy = printHierarchy;
13
+ exports.shortLink = shortLink;
14
+ exports.getDocumentationForType = getDocumentationForType;
13
15
  const typescript_1 = __importDefault(require("typescript"));
14
16
  const assert_1 = require("../../util/assert");
15
17
  const doc_files_1 = require("./doc-files");
@@ -18,6 +20,7 @@ const path_1 = __importDefault(require("path"));
18
20
  const mermaid_1 = require("../../util/mermaid/mermaid");
19
21
  const doc_code_1 = require("./doc-code");
20
22
  const doc_structure_1 = require("./doc-structure");
23
+ const html_hover_over_1 = require("../../util/html-hover-over");
21
24
  function getSourceFiles(fileNames) {
22
25
  try {
23
26
  const program = typescript_1.default.createProgram(fileNames, { target: typescript_1.default.ScriptTarget.ESNext });
@@ -171,6 +174,42 @@ function collectHierarchyInformation(sourceFiles, options) {
171
174
  }),
172
175
  });
173
176
  }
177
+ else if (typescript_1.default.isVariableDeclaration(node) || typescript_1.default.isExportDeclaration(node) || typescript_1.default.isExportAssignment(node) || typescript_1.default.isDeclarationStatement(node)) {
178
+ const name = node.name?.getText(sourceFile) ?? '';
179
+ const comments = getTextualComments(node);
180
+ hierarchyList.push({
181
+ name: dropGenericsFromType(name),
182
+ node,
183
+ kind: 'variable',
184
+ extends: [],
185
+ comments,
186
+ generics: [],
187
+ filePath: sourceFile.fileName,
188
+ lineNumber: getStartLine(node, sourceFile),
189
+ });
190
+ }
191
+ else if (typescript_1.default.isPropertyAssignment(node) || typescript_1.default.isPropertyDeclaration(node) || typescript_1.default.isPropertySignature(node)
192
+ || typescript_1.default.isMethodDeclaration(node) || typescript_1.default.isMethodSignature(node) || typescript_1.default.isFunctionDeclaration(node)) {
193
+ const name = node.name?.getText(sourceFile) ?? '';
194
+ // get the name of the object/enclosing type
195
+ let parent = node.parent;
196
+ while (typeof parent === 'object' && parent !== undefined && !('name' in parent)) {
197
+ parent = parent.parent;
198
+ }
199
+ if (typeof parent === 'object' && 'name' in parent) {
200
+ const comments = getTextualComments(node);
201
+ hierarchyList.push({
202
+ name: dropGenericsFromType(name),
203
+ node,
204
+ kind: 'variable',
205
+ extends: [parent.name?.getText(sourceFile) ?? ''],
206
+ comments,
207
+ generics: [],
208
+ filePath: sourceFile.fileName,
209
+ lineNumber: getStartLine(node, sourceFile),
210
+ });
211
+ }
212
+ }
174
213
  typescript_1.default.forEachChild(node, child => visit(child, sourceFile));
175
214
  };
176
215
  sourceFiles.forEach(sourceFile => {
@@ -266,7 +305,7 @@ function getTypesFromFolderAsMermaid(options) {
266
305
  }
267
306
  return getTypesFromFileAsMermaid(files, options);
268
307
  }
269
- function implSnippet(node, program, nesting = 0) {
308
+ function implSnippet(node, program, showName = true, nesting = 0) {
270
309
  (0, assert_1.guard)(node !== undefined, 'Node must be defined => invalid change of type name?');
271
310
  const indent = ' '.repeat(nesting * 2);
272
311
  const bold = node.kind === 'interface' || node.kind === 'enum' ? '**' : '';
@@ -274,7 +313,8 @@ function implSnippet(node, program, nesting = 0) {
274
313
  let text = node.comments?.join('\n') ?? '';
275
314
  const code = node.node.getFullText(program.getSourceFile(node.node.getSourceFile().fileName));
276
315
  text += `\n<details><summary style="color:gray">Defined at <a href="${getTypePathLink(node)}">${getTypePathLink(node, '.')}</a></summary>\n\n${(0, doc_code_1.codeBlock)('ts', code)}\n\n</details>\n`;
277
- return `${indent} * ${bold}[${node.name}](${getTypePathLink(node)})${bold} ${sep}${indent} ${text.replaceAll('\t', ' ').split(/\n/g).join(`\n${indent} `)}`;
316
+ const init = showName ? ` * ${bold}[${node.name}](${getTypePathLink(node)})${bold} ${sep}${indent}` : '';
317
+ return ` ${indent} ${showName ? init : ''} ${text.replaceAll('\t', ' ').split(/\n/g).join(`\n${indent} `)}`;
278
318
  }
279
319
  exports.mermaidHide = ['Leaf', 'Location', 'Namespace', 'Base', 'WithChildren', 'Partial', 'RAccessBase'];
280
320
  function printHierarchy({ program, hierarchy, root, collapseFromNesting = 1, initialNesting = 0, maxDepth = 20 }) {
@@ -285,7 +325,7 @@ function printHierarchy({ program, hierarchy, root, collapseFromNesting = 1, ini
285
325
  if (!node) {
286
326
  return '';
287
327
  }
288
- const thisLine = implSnippet(node, program, initialNesting);
328
+ const thisLine = implSnippet(node, program, true, initialNesting);
289
329
  const result = [];
290
330
  for (const baseType of node.extends) {
291
331
  if (exports.mermaidHide.includes(baseType)) {
@@ -302,4 +342,42 @@ function printHierarchy({ program, hierarchy, root, collapseFromNesting = 1, ini
302
342
  return thisLine + (out ? '\n' + out : '');
303
343
  }
304
344
  }
345
+ function retrieveNode(name, hierarchy) {
346
+ let container = undefined;
347
+ if (name.includes('::')) {
348
+ [container, name] = name.split('::');
349
+ }
350
+ const node = hierarchy.find(e => e.name === name);
351
+ if (!node) {
352
+ return undefined;
353
+ }
354
+ else if (container && !node.extends.includes(container)) {
355
+ return undefined;
356
+ }
357
+ return [container, name, node];
358
+ }
359
+ /**
360
+ * Create a short link to a type in the documentation
361
+ * @param name - The name of the type, e.g. `MyType`, may include a container, e.g. `MyContainer::MyType` (this works with function nestings too)
362
+ * @param hierarchy - The hierarchy of types to search in
363
+ * @param codeStyle - Whether to use code style for the link
364
+ */
365
+ function shortLink(name, hierarchy, codeStyle = true) {
366
+ const res = retrieveNode(name, hierarchy);
367
+ if (!res) {
368
+ return '';
369
+ }
370
+ const [pkg, mainName, node] = res;
371
+ const comments = node.comments?.join('\n').replace(/\\?\n|```[a-zA-Z]*|\s\s*/g, ' ').replace(/<\/?code>|/g, '') ?? '';
372
+ return `[${codeStyle ? '<code>' : ''}${(node.comments?.length ?? 0) > 0 ?
373
+ (0, html_hover_over_1.textWithTooltip)(pkg ? `${pkg}::<b>${mainName}</b>` : mainName, (0, mermaid_1.escapeMarkdown)(comments.length > 400 ? comments.slice(0, 400) + '...' : comments)) : node.name}${codeStyle ? '</code>' : ''}](${getTypePathLink(node)})`;
374
+ }
375
+ function getDocumentationForType(name, hierarchy) {
376
+ const res = retrieveNode(name, hierarchy);
377
+ if (!res) {
378
+ return '';
379
+ }
380
+ const [, , node] = res;
381
+ return node.comments?.join('\n') ?? '';
382
+ }
305
383
  //# sourceMappingURL=doc-types.js.map
@@ -689,7 +689,7 @@ async function getText(shell) {
689
689
  });
690
690
  return `${(0, doc_auto_gen_1.autoGenHeader)({ filename: module.filename, purpose: 'dataflow graph', rVersion: rversion })}
691
691
 
692
- This page briefly summarizes flowR's dataflow graph, represented by ${graph_1.DataflowGraph.name} in ${(0, doc_files_1.getFilePathMd)('../dataflow/graph/graph.ts')}.
692
+ This page briefly summarizes flowR's dataflow graph, represented by ${(0, doc_types_1.shortLink)('DataflowGraph', vertexType.info)} in ${(0, doc_files_1.getFilePathMd)('../dataflow/graph/graph.ts')}.
693
693
  In case you want to manually build such a graph (e.g., for testing), you can use the builder in ${(0, doc_files_1.getFilePathMd)('../dataflow/graph/dataflowgraph-builder.ts')}.
694
694
  This wiki page focuses on explaining what such a dataflow graph looks like!
695
695
 
@@ -1,4 +1,7 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
6
  const shell_1 = require("../r-bridge/shell");
4
7
  const log_1 = require("../../test/functionality/_helper/log");
@@ -19,6 +22,8 @@ const flowr_main_options_1 = require("../cli/flowr-main-options");
19
22
  const doc_issue_1 = require("./doc-util/doc-issue");
20
23
  const pipeline_executor_1 = require("../core/pipeline-executor");
21
24
  const doc_structure_1 = require("./doc-util/doc-structure");
25
+ const doc_types_1 = require("./doc-util/doc-types");
26
+ const path_1 = __importDefault(require("path"));
22
27
  async function explainServer(shell) {
23
28
  (0, doc_data_server_messages_1.documentAllServerMessages)();
24
29
  return `
@@ -234,37 +239,43 @@ ${(0, schema_1.describeSchema)(config_1.flowrConfigFileSchema, ansi_1.markdownFo
234
239
  `;
235
240
  }
236
241
  function explainWritingCode(shell) {
242
+ const types = (0, doc_types_1.getTypesFromFolderAsMermaid)({
243
+ rootFolder: path_1.default.resolve('./src/r-bridge/'),
244
+ files: [path_1.default.resolve('./src/core/pipeline-executor.ts'), path_1.default.resolve('./src/core/steps/pipeline/default-pipelines.ts')],
245
+ typeName: 'RShell',
246
+ inlineTypes: doc_types_1.mermaidHide
247
+ });
237
248
  return `
238
249
 
239
250
 
240
251
  _flowR_ can be used as a [module](${doc_files_1.FlowrNpmRef}) and offers several main classes and interfaces that are interesting for extension writers
241
252
  (see the [Visual Studio Code extension](${doc_files_1.FlowrGithubBaseRef}/vscode-flowr) or the [core](${doc_files_1.FlowrWikiBaseRef}/Core) wiki page for more information).
242
253
 
243
- ### Using the \`${shell_1.RShell.name}\` to Interact with R
254
+ ### Using the ${(0, doc_types_1.shortLink)(shell_1.RShell.name, types.info)} to Interact with R
244
255
 
245
- The \`${shell_1.RShell.name}\` class allows to interface with the \`R\`&nbsp;ecosystem installed on the host system.
256
+ The ${(0, doc_types_1.shortLink)(shell_1.RShell.name, types.info)} class allows interfacing with the \`R\`&nbsp;ecosystem installed on the host system.
246
257
  For now, there are no (real) alternatives, although we plan on providing more flexible drop-in replacements.
247
258
 
248
259
  > [!IMPORTANT]
249
- > Each \`${shell_1.RShell.name}\` controls a new instance of the R&nbsp;interpreter, make sure to call \`${shell_1.RShell.name}::${shell.close.name}()\` when you’re done.
260
+ > Each ${(0, doc_types_1.shortLink)(shell_1.RShell.name, types.info)} controls a new instance of the R&nbsp;interpreter, make sure to call <code>${(0, doc_types_1.shortLink)(shell_1.RShell.name, types.info, false)}::${shell.close.name}()</code> when you’re done.
250
261
 
251
- You can start a new "session" simply by constructing a new object with \`new ${shell_1.RShell.name}()\`.
262
+ You can start a new "session" simply by constructing a new object with <code>new ${(0, doc_types_1.shortLink)(shell_1.RShell.name, types.info, false)}()</code>.
252
263
 
253
- However, there are several options which may be of interest (e.g., to automatically revive the shell in case of errors or to control the name location of the R process on the system).
264
+ However, there are several options that may be of interest (e.g., to automatically revive the shell in case of errors or to control the name location of the R process on the system).
254
265
 
255
- With a shell object (let's call it \`shell\`), you can execute R code by using \`${shell_1.RShell.name}::${shell.sendCommand.name}\`,
266
+ With a shell object (let's call it \`shell\`), you can execute R code by using <code>${(0, doc_types_1.shortLink)(shell_1.RShell.name, types.info, false)}::${shell.sendCommand.name}</code>,
256
267
  for example \`shell.${shell.sendCommand.name}("1 + 1")\`.
257
- However, this does not return anything, so if you want to collect the output of your command, use \`${shell_1.RShell.name}::${shell.sendCommandWithOutput.name}\` instead.
268
+ However, this does not return anything, so if you want to collect the output of your command, use <code>${(0, doc_types_1.shortLink)(shell_1.RShell.name, types.info, false)}::${shell.sendCommandWithOutput.name}</code> instead.
258
269
 
259
- Besides that, the command \`${shell_1.RShell.name}::${shell.tryToInjectHomeLibPath.name}\` may be of interest, as it enables all libraries available on the host system.
270
+ Besides that, the command <code>${(0, doc_types_1.shortLink)(shell_1.RShell.name, types.info, false)}::${shell.tryToInjectHomeLibPath.name}</code> may be of interest, as it enables all libraries available on the host system.
260
271
 
261
272
  ### The Pipeline Executor
262
273
 
263
274
  Once, in the beginning, _flowR_ was meant to produce a dataflow graph merely to provide *program slices*.
264
- However, with continuous updates, the [dataflow graph](${doc_files_1.FlowrWikiBaseRef}/Dataflow&20Graph) repeatedly proves to be the more interesting part.
275
+ However, with continuous updates, the [dataflow graph](${doc_files_1.FlowrWikiBaseRef}/Dataflow%20Graph) repeatedly proves to be the more interesting part.
265
276
  With this, we restructured _flowR_'s originally *hardcoded* pipeline to be far more flexible.
266
277
  Now, it can be theoretically extended or replaced with arbitrary steps, optional steps, and what we call 'decorations' of these steps.
267
- In short, if you still "just want to slice" you can do it like this:
278
+ In short, if you still "just want to slice" you can do it like this with the ${(0, doc_types_1.shortLink)(pipeline_executor_1.PipelineExecutor.name, types.info)}:
268
279
 
269
280
  ${(0, doc_code_1.codeBlock)('ts', `
270
281
  const slicer = new ${pipeline_executor_1.PipelineExecutor.name}(DEFAULT_SLICING_PIPELINE, {
@@ -281,9 +292,9 @@ const slice = await slicer.allRemainingSteps()
281
292
  <summary style='color:gray'>More Information</summary>
282
293
 
283
294
  If you compare this, with what you would have done with the old (and removed) \`SteppingSlicer\`,
284
- this essentially just requires you to replace the \`SteppingSlicer\` with the \`${pipeline_executor_1.PipelineExecutor.name}\`
285
- and to pass the \`DEFAULT_SLICING_PIPELINE\` as the first argument.
286
- The \`${pipeline_executor_1.PipelineExecutor.name}\`...
295
+ this essentially just requires you to replace the \`SteppingSlicer\` with the ${(0, doc_types_1.shortLink)(pipeline_executor_1.PipelineExecutor.name, types.info)}
296
+ and to pass the ${(0, doc_types_1.shortLink)('DEFAULT_SLICING_PIPELINE', types.info)} as the first argument.
297
+ The ${(0, doc_types_1.shortLink)(pipeline_executor_1.PipelineExecutor.name, types.info)}...
287
298
 
288
299
  1. allows investigating the results of all intermediate steps
289
300
  2. Can be executed step-by-step
@@ -24,7 +24,7 @@ async function getText(shell) {
24
24
  const now = performance.now();
25
25
  const types = (0, doc_types_1.getTypesFromFolderAsMermaid)({
26
26
  rootFolder: path_1.default.resolve('./src/r-bridge/lang-4.x/ast/model/'),
27
- files: [path_1.default.resolve('./src/abstract-interpretation/normalized-ast-fold.ts')],
27
+ files: [path_1.default.resolve('./src/abstract-interpretation/normalized-ast-fold.ts'), path_1.default.resolve('./src/core/steps/pipeline/default-pipelines.ts')],
28
28
  typeName: 'RNode',
29
29
  inlineTypes: doc_types_1.mermaidHide
30
30
  });
@@ -77,7 +77,7 @@ ${(0, doc_code_1.codeBlock)('mermaid', types.text)}
77
77
  _The generation of the class diagram required ${(0, time_1.printAsMs)(elapsed)}._
78
78
  </details>
79
79
 
80
- Node types are controlled by the \`${'RType'}\` enum (see ${(0, doc_files_1.getFilePathMd)('../r-bridge/lang-4.x/ast/model/type.ts')}),
80
+ Node types are controlled by the ${(0, doc_types_1.shortLink)('RType', types.info)} enum (see ${(0, doc_files_1.getFilePathMd)('../r-bridge/lang-4.x/ast/model/type.ts')}),
81
81
  which is used to distinguish between different types of nodes.
82
82
  Additionally, every AST node is generic with respect to the \`Info\` type which allows for arbitrary decorations (e.g., parent inforamtion or dataflow constraints).
83
83
  Most notably, the \`info\` field holds the \`id\` of the node, which is used to reference the node in the [dataflow graph](${doc_files_1.FlowrWikiBaseRef}/Dataflow%20Graph).
@@ -94,8 +94,8 @@ The following segments intend to give you an overview of how to work with the no
94
94
  ## How Get a Normalized AST
95
95
 
96
96
  As explained alongside the [Interface](${doc_files_1.FlowrWikiBaseRef}/Interface#the-pipeline-executor) wiki page, you can use the
97
- \`${pipeline_executor_1.PipelineExecutor.name}\` to get the normalized AST. If you are only interested in the normalization,
98
- a pipeline like the \`DEFAULT_NORMALIZE_PIPELINE\` suffices:
97
+ \`${pipeline_executor_1.PipelineExecutor.name}\` to get the ${(0, doc_types_1.shortLink)('NormalizedAst', types.info)}. If you are only interested in the normalization,
98
+ a pipeline like the ${(0, doc_types_1.shortLink)('DEFAULT_NORMALIZE_PIPELINE', types.info)} suffices:
99
99
 
100
100
  ${(0, doc_code_1.codeBlock)('ts', `
101
101
  async function getAst(code: string): Promise<RNode> {
@@ -26,6 +26,9 @@ const doc_issue_1 = require("./doc-util/doc-issue");
26
26
  const location_map_query_executor_1 = require("../queries/catalog/location-map-query/location-map-query-executor");
27
27
  const identify_link_to_last_call_relation_1 = require("../queries/catalog/call-context-query/identify-link-to-last-call-relation");
28
28
  const config_query_executor_1 = require("../queries/catalog/config-query/config-query-executor");
29
+ const search_query_executor_1 = require("../queries/catalog/search-query/search-query-executor");
30
+ const flowr_search_builder_1 = require("../search/flowr-search-builder");
31
+ const vertex_1 = require("../dataflow/graph/vertex");
29
32
  (0, doc_query_1.registerQueryDocumentation)('call-context', {
30
33
  name: 'Call-Context Query',
31
34
  type: 'active',
@@ -191,6 +194,25 @@ ${await (0, doc_query_1.showQuery)(shell, example_query_code_1.exampleQueryCode,
191
194
  `;
192
195
  }
193
196
  });
197
+ (0, doc_query_1.registerQueryDocumentation)('search', {
198
+ name: 'Search Query',
199
+ type: 'active',
200
+ shortDescription: 'Provides access to flowR\'s search API',
201
+ functionName: search_query_executor_1.executeSearch.name,
202
+ functionFile: '../queries/catalog/search-query/search-query-executor.ts',
203
+ buildExplanation: async (shell) => {
204
+ const exampleCode = 'x + 1';
205
+ return `
206
+ With this query you can use the [Search API](${doc_files_1.FlowrWikiBaseRef}/Search%20API) to conduct searches on the flowR analysis result.
207
+
208
+ Using the example code \`${exampleCode}\`, the following query returns all uses of 'x' in the code:
209
+ ${await (0, doc_query_1.showQuery)(shell, exampleCode, [{
210
+ type: 'search',
211
+ search: flowr_search_builder_1.Q.var('x').filter(vertex_1.VertexType.Use).build()
212
+ }], { showCode: true, collapseQuery: false })}
213
+ `;
214
+ }
215
+ });
194
216
  (0, doc_query_1.registerQueryDocumentation)('id-map', {
195
217
  name: 'Id-Map Query',
196
218
  type: 'active',
@@ -0,0 +1 @@
1
+ export {};