@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.
- package/README.md +1 -0
- package/cli/repl/commands/repl-query.js +1 -1
- package/cli/repl/server/connection.js +1 -1
- package/core/steps/pipeline/default-pipelines.d.ts +6 -0
- package/core/steps/pipeline/default-pipelines.js +6 -0
- package/dataflow/graph/vertex.d.ts +4 -0
- package/dataflow/graph/vertex.js +3 -1
- package/documentation/doc-util/doc-dfg.js +1 -1
- package/documentation/doc-util/doc-query.js +1 -1
- package/documentation/doc-util/doc-search.d.ts +25 -0
- package/documentation/doc-util/doc-search.js +121 -0
- package/documentation/doc-util/doc-types.d.ts +10 -2
- package/documentation/doc-util/doc-types.js +81 -3
- package/documentation/print-dataflow-graph-wiki.js +1 -1
- package/documentation/print-interface-wiki.js +24 -13
- package/documentation/print-normalized-ast-wiki.js +4 -4
- package/documentation/print-query-wiki.js +22 -0
- package/documentation/print-search-wiki.d.ts +1 -0
- package/documentation/print-search-wiki.js +74 -0
- package/package.json +2 -1
- package/queries/base-query-format.d.ts +2 -2
- package/queries/catalog/call-context-query/call-context-query-executor.d.ts +1 -1
- package/queries/catalog/call-context-query/call-context-query-executor.js +1 -1
- package/queries/catalog/cluster-query/cluster-query-executor.d.ts +1 -1
- package/queries/catalog/cluster-query/cluster-query-executor.js +1 -1
- package/queries/catalog/dataflow-query/dataflow-query-executor.d.ts +1 -1
- package/queries/catalog/dataflow-query/dataflow-query-executor.js +1 -1
- package/queries/catalog/dependencies-query/dependencies-query-executor.js +2 -2
- package/queries/catalog/lineage-query/lineage-query-executor.d.ts +1 -1
- package/queries/catalog/lineage-query/lineage-query-executor.js +1 -1
- package/queries/catalog/search-query/search-query-executor.d.ts +3 -0
- package/queries/catalog/search-query/search-query-executor.js +27 -0
- package/queries/catalog/search-query/search-query-format.d.ts +72 -0
- package/queries/catalog/search-query/search-query-format.js +29 -0
- package/queries/catalog/static-slice-query/static-slice-query-executor.d.ts +1 -1
- package/queries/catalog/static-slice-query/static-slice-query-executor.js +1 -1
- package/queries/query.d.ts +59 -1
- package/queries/query.js +3 -1
- package/r-bridge/lang-4.x/ast/model/type.d.ts +4 -0
- package/r-bridge/lang-4.x/ast/model/type.js +3 -1
- package/search/flowr-search-builder.d.ts +193 -0
- package/search/flowr-search-builder.js +192 -0
- package/search/flowr-search-executor.d.ts +9 -0
- package/search/flowr-search-executor.js +16 -0
- package/search/flowr-search-filters.d.ts +74 -0
- package/search/flowr-search-filters.js +136 -0
- package/search/flowr-search-printer.d.ts +10 -0
- package/search/flowr-search-printer.js +85 -0
- package/search/flowr-search-traverse.d.ts +7 -0
- package/search/flowr-search-traverse.js +12 -0
- package/search/flowr-search.d.ts +58 -0
- package/search/flowr-search.js +29 -0
- package/search/search-executor/search-generators.d.ts +37 -0
- package/search/search-executor/search-generators.js +64 -0
- package/search/search-executor/search-transformer.d.ts +57 -0
- package/search/search-executor/search-transformer.js +99 -0
- package/search/search-optimizer/search-optimizer.d.ts +9 -0
- package/search/search-optimizer/search-optimizer.js +89 -0
- package/util/arrays.d.ts +13 -0
- package/util/assert.d.ts +1 -1
- package/util/mermaid/mermaid.js +17 -0
- package/util/version.js +1 -1
package/README.md
CHANGED
|
@@ -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)({
|
|
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)({
|
|
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
|
*
|
package/dataflow/graph/vertex.js
CHANGED
|
@@ -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)}_ (
|
|
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)({
|
|
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
|
-
|
|
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 ${
|
|
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
|
|
254
|
+
### Using the ${(0, doc_types_1.shortLink)(shell_1.RShell.name, types.info)} to Interact with R
|
|
244
255
|
|
|
245
|
-
The
|
|
256
|
+
The ${(0, doc_types_1.shortLink)(shell_1.RShell.name, types.info)} class allows interfacing with the \`R\` 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
|
|
260
|
+
> Each ${(0, doc_types_1.shortLink)(shell_1.RShell.name, types.info)} controls a new instance of the R 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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
285
|
-
and to pass the
|
|
286
|
-
The
|
|
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
|
|
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
|
|
98
|
-
a pipeline like the
|
|
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 {};
|