@eagleoutice/flowr 2.2.14 → 2.2.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +210 -6
- package/benchmark/slicer.d.ts +3 -1
- package/benchmark/slicer.js +8 -5
- package/benchmark/summarizer/first-phase/process.d.ts +2 -1
- package/benchmark/summarizer/first-phase/process.js +2 -2
- package/cli/benchmark-app.d.ts +1 -0
- package/cli/benchmark-app.js +4 -1
- package/cli/benchmark-helper-app.d.ts +1 -0
- package/cli/benchmark-helper-app.js +7 -8
- package/cli/common/options.js +2 -0
- package/cli/export-quads-app.js +2 -1
- package/cli/flowr.js +58 -57
- package/cli/repl/commands/repl-cfg.js +13 -13
- package/cli/repl/commands/repl-commands.js +3 -3
- package/cli/repl/commands/repl-dataflow.js +10 -10
- package/cli/repl/commands/repl-execute.d.ts +2 -3
- package/cli/repl/commands/repl-execute.js +5 -4
- package/cli/repl/commands/repl-lineage.js +4 -4
- package/cli/repl/commands/repl-main.d.ts +12 -1
- package/cli/repl/commands/repl-normalize.js +6 -6
- package/cli/repl/commands/repl-parse.js +2 -2
- package/cli/repl/commands/repl-query.js +9 -9
- package/cli/repl/commands/repl-version.js +1 -1
- package/cli/repl/core.d.ts +5 -2
- package/cli/repl/core.js +10 -8
- package/cli/repl/server/connection.d.ts +3 -1
- package/cli/repl/server/connection.js +7 -5
- package/cli/repl/server/server.d.ts +3 -2
- package/cli/repl/server/server.js +4 -2
- package/cli/script-core/statistics-core.d.ts +2 -1
- package/cli/script-core/statistics-core.js +2 -2
- package/cli/script-core/statistics-helper-core.d.ts +2 -1
- package/cli/script-core/statistics-helper-core.js +5 -4
- package/cli/slicer-app.js +4 -2
- package/cli/statistics-app.js +2 -1
- package/cli/statistics-helper-app.js +2 -1
- package/config.d.ts +12 -10
- package/config.js +27 -43
- package/control-flow/basic-cfg-guided-visitor.d.ts +3 -3
- package/control-flow/cfg-dead-code.d.ts +4 -0
- package/control-flow/cfg-dead-code.js +124 -0
- package/control-flow/cfg-simplification.d.ts +19 -6
- package/control-flow/cfg-simplification.js +23 -19
- package/control-flow/control-flow-graph.d.ts +3 -1
- package/control-flow/control-flow-graph.js +5 -0
- package/control-flow/dfg-cfg-guided-visitor.d.ts +9 -7
- package/control-flow/dfg-cfg-guided-visitor.js +16 -5
- package/control-flow/extract-cfg.d.ts +4 -2
- package/control-flow/extract-cfg.js +63 -59
- package/control-flow/semantic-cfg-guided-visitor.d.ts +36 -9
- package/control-flow/semantic-cfg-guided-visitor.js +73 -20
- package/control-flow/simple-visitor.d.ts +4 -0
- package/control-flow/simple-visitor.js +14 -0
- package/control-flow/syntax-cfg-guided-visitor.d.ts +2 -2
- package/core/pipeline-executor.d.ts +4 -1
- package/core/pipeline-executor.js +6 -5
- package/core/steps/all/core/10-normalize.d.ts +2 -0
- package/core/steps/all/core/10-normalize.js +1 -1
- package/core/steps/all/core/11-normalize-tree-sitter.d.ts +2 -1
- package/core/steps/all/core/11-normalize-tree-sitter.js +2 -2
- package/core/steps/all/core/20-dataflow.d.ts +2 -1
- package/core/steps/all/core/20-dataflow.js +2 -2
- package/core/steps/all/static-slicing/00-slice.d.ts +2 -1
- package/core/steps/all/static-slicing/00-slice.js +2 -2
- package/core/steps/pipeline/default-pipelines.d.ts +32 -31
- package/core/steps/pipeline/default-pipelines.js +8 -8
- package/core/steps/pipeline-step.d.ts +2 -1
- package/dataflow/environments/built-in-config.d.ts +4 -3
- package/dataflow/environments/built-in.d.ts +16 -1
- package/dataflow/environments/built-in.js +11 -5
- package/dataflow/environments/default-builtin-config.js +5 -3
- package/dataflow/environments/define.d.ts +2 -1
- package/dataflow/environments/define.js +4 -5
- package/dataflow/environments/remove.d.ts +6 -0
- package/dataflow/environments/remove.js +29 -0
- package/dataflow/environments/resolve-by-name.d.ts +0 -36
- package/dataflow/environments/resolve-by-name.js +0 -240
- package/dataflow/eval/resolve/alias-tracking.d.ts +92 -0
- package/dataflow/eval/resolve/alias-tracking.js +352 -0
- package/dataflow/eval/resolve/resolve-argument.d.ts +8 -0
- package/dataflow/eval/resolve/resolve-argument.js +118 -0
- package/dataflow/eval/resolve/resolve.d.ts +37 -0
- package/dataflow/eval/resolve/resolve.js +95 -0
- package/dataflow/eval/values/general.d.ts +27 -0
- package/dataflow/eval/values/general.js +73 -0
- package/dataflow/eval/values/intervals/interval-constants.d.ts +4 -0
- package/dataflow/eval/values/intervals/interval-constants.js +27 -0
- package/dataflow/eval/values/logical/logical-constants.d.ts +7 -0
- package/dataflow/eval/values/logical/logical-constants.js +31 -0
- package/dataflow/eval/values/r-value.d.ts +58 -0
- package/dataflow/eval/values/r-value.js +90 -0
- package/dataflow/eval/values/scalar/scalar-consatnts.d.ts +15 -0
- package/dataflow/eval/values/scalar/scalar-consatnts.js +35 -0
- package/dataflow/eval/values/sets/set-constants.d.ts +7 -0
- package/dataflow/eval/values/sets/set-constants.js +34 -0
- package/dataflow/eval/values/string/string-constants.d.ts +8 -0
- package/dataflow/eval/values/string/string-constants.js +45 -0
- package/dataflow/eval/values/vectors/vector-constants.d.ts +14 -0
- package/dataflow/eval/values/vectors/vector-constants.js +35 -0
- package/dataflow/extractor.d.ts +2 -1
- package/dataflow/extractor.js +2 -1
- package/dataflow/graph/unknown-replacement.d.ts +11 -0
- package/dataflow/graph/unknown-replacement.js +12 -0
- package/dataflow/graph/unknown-side-effect.d.ts +7 -0
- package/dataflow/graph/unknown-side-effect.js +13 -0
- package/dataflow/internal/process/functions/call/built-in/built-in-access.js +5 -6
- package/dataflow/internal/process/functions/call/built-in/built-in-apply.js +8 -5
- package/dataflow/internal/process/functions/call/built-in/built-in-assignment.d.ts +4 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-assignment.js +15 -13
- package/dataflow/internal/process/functions/call/built-in/built-in-eval.js +20 -18
- package/dataflow/internal/process/functions/call/built-in/built-in-expression-list.js +7 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-for-loop.js +2 -3
- package/dataflow/internal/process/functions/call/built-in/built-in-if-then-else.js +5 -4
- package/dataflow/internal/process/functions/call/built-in/built-in-list.js +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-replacement.js +11 -5
- package/dataflow/internal/process/functions/call/built-in/built-in-source.d.ts +5 -3
- package/dataflow/internal/process/functions/call/built-in/built-in-source.js +26 -29
- package/dataflow/internal/process/functions/call/built-in/built-in-vector.js +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-while-loop.js +23 -0
- package/dataflow/internal/process/functions/call/common.js +1 -1
- package/dataflow/internal/process/functions/call/known-call-handling.js +2 -1
- package/dataflow/internal/process/functions/process-parameter.js +1 -1
- package/dataflow/origin/dfg-get-symbol-refs.d.ts +21 -0
- package/dataflow/origin/dfg-get-symbol-refs.js +50 -0
- package/dataflow/processor.d.ts +5 -0
- package/documentation/doc-util/doc-cfg.js +4 -3
- package/documentation/doc-util/doc-code.d.ts +1 -1
- package/documentation/doc-util/doc-dfg.js +3 -2
- package/documentation/doc-util/doc-functions.d.ts +24 -0
- package/documentation/doc-util/doc-functions.js +65 -0
- package/documentation/doc-util/doc-normalized-ast.js +3 -2
- package/documentation/doc-util/doc-print.d.ts +5 -0
- package/documentation/doc-util/doc-print.js +36 -0
- package/documentation/doc-util/doc-query.d.ts +6 -3
- package/documentation/doc-util/doc-query.js +6 -3
- package/documentation/doc-util/doc-repl.js +2 -1
- package/documentation/doc-util/doc-search.js +3 -2
- package/documentation/doc-util/doc-types.d.ts +28 -6
- package/documentation/doc-util/doc-types.js +89 -45
- package/documentation/print-cfg-wiki.js +10 -11
- package/documentation/print-core-wiki.js +5 -5
- package/documentation/print-dataflow-graph-wiki.js +14 -13
- package/documentation/print-engines-wiki.js +2 -3
- package/documentation/print-faq-wiki.js +8 -2
- package/documentation/print-interface-wiki.js +1 -2
- package/documentation/print-linter-issue.d.ts +1 -0
- package/documentation/print-linter-issue.js +71 -0
- package/documentation/print-linter-wiki.js +219 -34
- package/documentation/print-linting-and-testing-wiki.js +2 -4
- package/documentation/print-normalized-ast-wiki.js +3 -3
- package/documentation/print-query-wiki.js +81 -2
- package/documentation/print-readme.js +24 -1
- package/documentation/print-search-wiki.js +1 -2
- package/linter/linter-executor.d.ts +3 -1
- package/linter/linter-executor.js +3 -2
- package/linter/linter-format.d.ts +67 -7
- package/linter/linter-format.js +12 -1
- package/linter/linter-rules.d.ts +155 -16
- package/linter/linter-rules.js +12 -4
- package/linter/linter-tags.d.ts +80 -0
- package/linter/linter-tags.js +85 -0
- package/linter/rules/absolute-path.d.ts +71 -0
- package/linter/rules/absolute-path.js +177 -0
- package/linter/rules/deprecated-functions.d.ts +43 -0
- package/linter/rules/deprecated-functions.js +58 -0
- package/linter/rules/{2-file-path-validity.d.ts → file-path-validity.d.ts} +16 -6
- package/linter/rules/{2-file-path-validity.js → file-path-validity.js} +21 -13
- package/linter/rules/naming-convention.d.ts +71 -0
- package/linter/rules/naming-convention.js +164 -0
- package/linter/rules/seeded-randomness.d.ts +65 -0
- package/linter/rules/seeded-randomness.js +122 -0
- package/linter/rules/unused-definition.d.ts +41 -0
- package/linter/rules/unused-definition.js +105 -0
- package/package.json +4 -1
- package/queries/base-query-format.d.ts +2 -0
- 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 +2 -2
- package/queries/catalog/cluster-query/cluster-query-format.d.ts +1 -1
- package/queries/catalog/config-query/config-query-executor.d.ts +1 -1
- package/queries/catalog/config-query/config-query-executor.js +2 -3
- package/queries/catalog/control-flow-query/control-flow-query-executor.d.ts +3 -0
- package/queries/catalog/control-flow-query/control-flow-query-executor.js +20 -0
- package/queries/catalog/control-flow-query/control-flow-query-format.d.ts +81 -0
- package/queries/catalog/control-flow-query/control-flow-query-format.js +34 -0
- package/queries/catalog/dataflow-lens-query/dataflow-lens-query-format.d.ts +1 -1
- package/queries/catalog/dataflow-query/dataflow-query-format.d.ts +1 -1
- package/queries/catalog/dependencies-query/dependencies-query-executor.js +4 -115
- package/queries/catalog/dependencies-query/dependencies-query-format.d.ts +1 -1
- package/queries/catalog/happens-before-query/happens-before-query-format.d.ts +1 -1
- package/queries/catalog/id-map-query/id-map-query-format.d.ts +1 -1
- package/queries/catalog/lineage-query/lineage-query-format.d.ts +1 -1
- package/queries/catalog/linter-query/linter-query-executor.d.ts +1 -1
- package/queries/catalog/linter-query/linter-query-executor.js +2 -2
- package/queries/catalog/linter-query/linter-query-format.d.ts +1 -1
- package/queries/catalog/linter-query/linter-query-format.js +17 -12
- package/queries/catalog/normalized-ast-query/normalized-ast-query-format.d.ts +1 -1
- package/queries/catalog/origin-query/origin-query-format.d.ts +1 -1
- package/queries/catalog/project-query/project-query-format.d.ts +1 -1
- package/queries/catalog/resolve-value-query/resolve-value-query-executor.d.ts +1 -1
- package/queries/catalog/resolve-value-query/resolve-value-query-executor.js +4 -4
- package/queries/catalog/resolve-value-query/resolve-value-query-format.d.ts +3 -2
- package/queries/catalog/resolve-value-query/resolve-value-query-format.js +2 -22
- package/queries/catalog/search-query/search-query-executor.d.ts +1 -1
- package/queries/catalog/search-query/search-query-executor.js +2 -2
- package/queries/catalog/search-query/search-query-format.d.ts +1 -1
- 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 +2 -2
- package/queries/catalog/static-slice-query/static-slice-query-format.d.ts +1 -1
- package/queries/query.d.ts +75 -15
- package/queries/query.js +2 -0
- package/r-bridge/lang-4.x/ast/parser/json/parser.d.ts +2 -1
- package/r-bridge/lang-4.x/ast/parser/json/parser.js +4 -2
- package/r-bridge/lang-4.x/convert-values.js +2 -1
- package/r-bridge/lang-4.x/tree-sitter/tree-sitter-executor.d.ts +3 -1
- package/r-bridge/lang-4.x/tree-sitter/tree-sitter-executor.js +4 -4
- package/r-bridge/lang-4.x/tree-sitter/tree-sitter-normalize.d.ts +1 -1
- package/r-bridge/lang-4.x/tree-sitter/tree-sitter-normalize.js +18 -9
- package/r-bridge/shell.d.ts +3 -2
- package/r-bridge/shell.js +4 -5
- package/search/flowr-search-builder.d.ts +6 -2
- package/search/flowr-search-builder.js +7 -0
- package/search/flowr-search-filters.d.ts +32 -8
- package/search/flowr-search-filters.js +42 -15
- package/search/flowr-search.d.ts +4 -0
- package/search/search-executor/search-enrichers.d.ts +7 -3
- package/search/search-executor/search-enrichers.js +32 -20
- package/search/search-executor/search-generators.js +1 -1
- package/search/search-executor/search-transformer.d.ts +2 -0
- package/search/search-executor/search-transformer.js +10 -1
- package/slicing/criterion/parse.d.ts +8 -0
- package/slicing/criterion/parse.js +20 -0
- package/slicing/static/static-slicer.d.ts +1 -1
- package/slicing/static/static-slicer.js +2 -3
- package/statistics/statistics.d.ts +3 -1
- package/statistics/statistics.js +5 -4
- package/util/containers.d.ts +12 -9
- package/util/containers.js +12 -9
- package/util/objects.d.ts +5 -4
- package/util/range.d.ts +5 -1
- package/util/range.js +11 -3
- package/util/text/strings.d.ts +6 -0
- package/util/text/strings.js +35 -0
- package/util/version.js +1 -1
- package/linter/rules/1-deprecated-functions.d.ts +0 -34
- package/linter/rules/1-deprecated-functions.js +0 -54
|
@@ -4,14 +4,21 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.mermaidHide = void 0;
|
|
7
|
+
exports.getTypeScriptSourceFiles = getTypeScriptSourceFiles;
|
|
8
|
+
exports.dropGenericsFromTypeName = dropGenericsFromTypeName;
|
|
9
|
+
exports.removeCommentSymbolsFromTypeScriptComment = removeCommentSymbolsFromTypeScriptComment;
|
|
10
|
+
exports.getTextualCommentsFromTypeScript = getTextualCommentsFromTypeScript;
|
|
11
|
+
exports.getStartLineOfTypeScriptNode = getStartLineOfTypeScriptNode;
|
|
7
12
|
exports.getType = getType;
|
|
8
13
|
exports.followTypeReference = followTypeReference;
|
|
14
|
+
exports.getTypePathForTypeScript = getTypePathForTypeScript;
|
|
9
15
|
exports.getTypePathLink = getTypePathLink;
|
|
10
|
-
exports.
|
|
16
|
+
exports.getTypesFromFolder = getTypesFromFolder;
|
|
11
17
|
exports.implSnippet = implSnippet;
|
|
12
18
|
exports.printHierarchy = printHierarchy;
|
|
13
19
|
exports.printCodeOfElement = printCodeOfElement;
|
|
14
20
|
exports.shortLink = shortLink;
|
|
21
|
+
exports.shortLinkFile = shortLinkFile;
|
|
15
22
|
exports.getDocumentationForType = getDocumentationForType;
|
|
16
23
|
const typescript_1 = __importDefault(require("typescript"));
|
|
17
24
|
const assert_1 = require("../../util/assert");
|
|
@@ -23,7 +30,7 @@ const doc_code_1 = require("./doc-code");
|
|
|
23
30
|
const doc_structure_1 = require("./doc-structure");
|
|
24
31
|
const html_hover_over_1 = require("../../util/html-hover-over");
|
|
25
32
|
const doc_general_1 = require("./doc-general");
|
|
26
|
-
function
|
|
33
|
+
function getTypeScriptSourceFiles(fileNames) {
|
|
27
34
|
try {
|
|
28
35
|
const program = typescript_1.default.createProgram(fileNames, { target: typescript_1.default.ScriptTarget.ESNext });
|
|
29
36
|
return { program, files: fileNames.map(fileName => program.getSourceFile(fileName)).filter(file => !!file) };
|
|
@@ -33,7 +40,7 @@ function getSourceFiles(fileNames) {
|
|
|
33
40
|
return { files: [], program: undefined };
|
|
34
41
|
}
|
|
35
42
|
}
|
|
36
|
-
function
|
|
43
|
+
function dropGenericsFromTypeName(type) {
|
|
37
44
|
let previous;
|
|
38
45
|
do {
|
|
39
46
|
previous = type;
|
|
@@ -41,7 +48,7 @@ function dropGenericsFromType(type) {
|
|
|
41
48
|
} while (type !== previous);
|
|
42
49
|
return type;
|
|
43
50
|
}
|
|
44
|
-
function
|
|
51
|
+
function removeCommentSymbolsFromTypeScriptComment(comment) {
|
|
45
52
|
return comment
|
|
46
53
|
// remove '/** \n * \n */...
|
|
47
54
|
.replace(/^\/\*\*?/gm, '').replace(/^\s*\*\s*/gm, '').replace(/\*\/$/gm, '').replace(/^\s*\*/gm, '')
|
|
@@ -49,22 +56,22 @@ function removeCommentSymbols(comment) {
|
|
|
49
56
|
.replace(/\{@[a-zA-Z]+ ([^}]+\|)?(?<name>[^}]+)}/gm, '<code>$<name></code>')
|
|
50
57
|
.trim();
|
|
51
58
|
}
|
|
52
|
-
function
|
|
59
|
+
function getTextualCommentsFromTypeScript(node) {
|
|
53
60
|
const comments = typescript_1.default.getJSDocCommentsAndTags(node);
|
|
54
61
|
const out = [];
|
|
55
62
|
for (const { comment } of comments) {
|
|
56
63
|
if (typeof comment === 'string') {
|
|
57
|
-
out.push(
|
|
64
|
+
out.push(removeCommentSymbolsFromTypeScriptComment(comment));
|
|
58
65
|
}
|
|
59
66
|
else if (comment !== undefined) {
|
|
60
67
|
for (const c of comment) {
|
|
61
|
-
out.push(
|
|
68
|
+
out.push(removeCommentSymbolsFromTypeScriptComment(c.getText(c.getSourceFile())));
|
|
62
69
|
}
|
|
63
70
|
}
|
|
64
71
|
}
|
|
65
72
|
return out;
|
|
66
73
|
}
|
|
67
|
-
function
|
|
74
|
+
function getStartLineOfTypeScriptNode(node, sourceFile) {
|
|
68
75
|
const lineStart = sourceFile.getLineAndCharacterOfPosition(node.getStart(sourceFile)).line;
|
|
69
76
|
return lineStart + 1;
|
|
70
77
|
}
|
|
@@ -97,17 +104,17 @@ function collectHierarchyInformation(sourceFiles, options) {
|
|
|
97
104
|
const interfaceName = node.name?.getText(sourceFile) ?? '';
|
|
98
105
|
const baseTypes = node.heritageClauses?.flatMap(clause => clause.types
|
|
99
106
|
.map(type => type.getText(sourceFile) ?? '')
|
|
100
|
-
.map(
|
|
107
|
+
.map(dropGenericsFromTypeName)) ?? [];
|
|
101
108
|
const generics = node.typeParameters?.map(param => param.getText(sourceFile) ?? '') || [];
|
|
102
109
|
hierarchyList.push({
|
|
103
|
-
name:
|
|
110
|
+
name: dropGenericsFromTypeName(interfaceName),
|
|
104
111
|
node,
|
|
105
112
|
kind: 'interface',
|
|
106
113
|
extends: baseTypes,
|
|
107
114
|
generics,
|
|
108
|
-
comments:
|
|
115
|
+
comments: getTextualCommentsFromTypeScript(node),
|
|
109
116
|
filePath: sourceFile.fileName,
|
|
110
|
-
lineNumber:
|
|
117
|
+
lineNumber: getStartLineOfTypeScriptNode(node, sourceFile),
|
|
111
118
|
properties: node.members.map(member => {
|
|
112
119
|
const name = member.name?.getText(sourceFile) ?? '';
|
|
113
120
|
return `${name}${(0, mermaid_1.escapeMarkdown)(': ' + getType(member, typeChecker))}`;
|
|
@@ -121,55 +128,69 @@ function collectHierarchyInformation(sourceFiles, options) {
|
|
|
121
128
|
baseTypes = node.type.types
|
|
122
129
|
.filter(typeNode => typescript_1.default.isTypeReferenceNode(typeNode))
|
|
123
130
|
.flatMap(typeName => followTypeReference(typeName, sourceFile))
|
|
124
|
-
.map(
|
|
131
|
+
.map(dropGenericsFromTypeName);
|
|
125
132
|
}
|
|
126
133
|
else if (typescript_1.default.isTypeReferenceNode(node.type)) {
|
|
127
|
-
baseTypes = [...followTypeReference(node.type, sourceFile)].map(
|
|
134
|
+
baseTypes = [...followTypeReference(node.type, sourceFile)].map(dropGenericsFromTypeName);
|
|
128
135
|
}
|
|
129
136
|
const generics = node.typeParameters?.map(param => param.getText(sourceFile) ?? '') ?? [];
|
|
130
137
|
hierarchyList.push({
|
|
131
|
-
name:
|
|
138
|
+
name: dropGenericsFromTypeName(typeName),
|
|
132
139
|
node,
|
|
133
140
|
kind: 'type',
|
|
134
141
|
extends: baseTypes,
|
|
135
|
-
comments:
|
|
142
|
+
comments: getTextualCommentsFromTypeScript(node),
|
|
136
143
|
generics,
|
|
137
144
|
filePath: sourceFile.fileName,
|
|
138
|
-
lineNumber:
|
|
145
|
+
lineNumber: getStartLineOfTypeScriptNode(node, sourceFile),
|
|
139
146
|
});
|
|
140
147
|
}
|
|
141
148
|
else if (typescript_1.default.isEnumDeclaration(node)) {
|
|
142
149
|
const enumName = node.name?.getText(sourceFile) ?? '';
|
|
143
150
|
hierarchyList.push({
|
|
144
|
-
name:
|
|
151
|
+
name: dropGenericsFromTypeName(enumName),
|
|
145
152
|
node,
|
|
146
153
|
kind: 'enum',
|
|
147
154
|
extends: [],
|
|
148
|
-
comments:
|
|
155
|
+
comments: getTextualCommentsFromTypeScript(node),
|
|
149
156
|
generics: [],
|
|
150
157
|
filePath: sourceFile.fileName,
|
|
151
|
-
lineNumber:
|
|
158
|
+
lineNumber: getStartLineOfTypeScriptNode(node, sourceFile),
|
|
152
159
|
properties: node.members.map(member => {
|
|
153
160
|
const name = member.name?.getText(sourceFile) ?? '';
|
|
154
161
|
return `${name}${(0, mermaid_1.escapeMarkdown)(': ' + getType(member, typeChecker))}`;
|
|
155
162
|
})
|
|
156
163
|
});
|
|
157
164
|
}
|
|
165
|
+
else if (typescript_1.default.isEnumMember(node)) {
|
|
166
|
+
const typeName = node.parent.name?.getText(sourceFile) ?? '';
|
|
167
|
+
const enumName = dropGenericsFromTypeName(typeName);
|
|
168
|
+
hierarchyList.push({
|
|
169
|
+
name: dropGenericsFromTypeName(node.name.getText(sourceFile)),
|
|
170
|
+
node,
|
|
171
|
+
kind: 'enum',
|
|
172
|
+
extends: [enumName],
|
|
173
|
+
comments: getTextualCommentsFromTypeScript(node),
|
|
174
|
+
generics: [],
|
|
175
|
+
filePath: sourceFile.fileName,
|
|
176
|
+
lineNumber: getStartLineOfTypeScriptNode(node, sourceFile),
|
|
177
|
+
});
|
|
178
|
+
}
|
|
158
179
|
else if (typescript_1.default.isClassDeclaration(node)) {
|
|
159
180
|
const className = node.name?.getText(sourceFile) ?? '';
|
|
160
181
|
const baseTypes = node.heritageClauses?.flatMap(clause => clause.types
|
|
161
182
|
.map(type => type.getText(sourceFile) ?? '')
|
|
162
|
-
.map(
|
|
183
|
+
.map(dropGenericsFromTypeName)) ?? [];
|
|
163
184
|
const generics = node.typeParameters?.map(param => param.getText(sourceFile) ?? '') ?? [];
|
|
164
185
|
hierarchyList.push({
|
|
165
|
-
name:
|
|
186
|
+
name: dropGenericsFromTypeName(className),
|
|
166
187
|
node,
|
|
167
188
|
kind: 'class',
|
|
168
189
|
extends: baseTypes,
|
|
169
|
-
comments:
|
|
190
|
+
comments: getTextualCommentsFromTypeScript(node),
|
|
170
191
|
generics,
|
|
171
192
|
filePath: sourceFile.fileName,
|
|
172
|
-
lineNumber:
|
|
193
|
+
lineNumber: getStartLineOfTypeScriptNode(node, sourceFile),
|
|
173
194
|
properties: node.members.map(member => {
|
|
174
195
|
const name = member.name?.getText(sourceFile) ?? '';
|
|
175
196
|
return `${name}${(0, mermaid_1.escapeMarkdown)(': ' + getType(member, typeChecker))}`;
|
|
@@ -178,16 +199,16 @@ function collectHierarchyInformation(sourceFiles, options) {
|
|
|
178
199
|
}
|
|
179
200
|
else if (typescript_1.default.isVariableDeclaration(node) || typescript_1.default.isExportDeclaration(node) || typescript_1.default.isExportAssignment(node) || typescript_1.default.isDeclarationStatement(node)) {
|
|
180
201
|
const name = node.name?.getText(sourceFile) ?? '';
|
|
181
|
-
const comments =
|
|
202
|
+
const comments = getTextualCommentsFromTypeScript(node);
|
|
182
203
|
hierarchyList.push({
|
|
183
|
-
name:
|
|
204
|
+
name: dropGenericsFromTypeName(name),
|
|
184
205
|
node,
|
|
185
206
|
kind: 'variable',
|
|
186
207
|
extends: [],
|
|
187
208
|
comments,
|
|
188
209
|
generics: [],
|
|
189
210
|
filePath: sourceFile.fileName,
|
|
190
|
-
lineNumber:
|
|
211
|
+
lineNumber: getStartLineOfTypeScriptNode(node, sourceFile),
|
|
191
212
|
});
|
|
192
213
|
}
|
|
193
214
|
else if (typescript_1.default.isPropertyAssignment(node) || typescript_1.default.isPropertyDeclaration(node) || typescript_1.default.isPropertySignature(node)
|
|
@@ -199,16 +220,16 @@ function collectHierarchyInformation(sourceFiles, options) {
|
|
|
199
220
|
parent = parent.parent;
|
|
200
221
|
}
|
|
201
222
|
if (typeof parent === 'object' && 'name' in parent) {
|
|
202
|
-
const comments =
|
|
223
|
+
const comments = getTextualCommentsFromTypeScript(node);
|
|
203
224
|
hierarchyList.push({
|
|
204
|
-
name:
|
|
225
|
+
name: dropGenericsFromTypeName(name),
|
|
205
226
|
node,
|
|
206
227
|
kind: 'variable',
|
|
207
228
|
extends: [parent.name?.getText(sourceFile) ?? ''],
|
|
208
229
|
comments,
|
|
209
230
|
generics: [],
|
|
210
231
|
filePath: sourceFile.fileName,
|
|
211
|
-
lineNumber:
|
|
232
|
+
lineNumber: getStartLineOfTypeScriptNode(node, sourceFile),
|
|
212
233
|
});
|
|
213
234
|
}
|
|
214
235
|
}
|
|
@@ -219,9 +240,12 @@ function collectHierarchyInformation(sourceFiles, options) {
|
|
|
219
240
|
});
|
|
220
241
|
return hierarchyList;
|
|
221
242
|
}
|
|
222
|
-
function
|
|
223
|
-
|
|
224
|
-
|
|
243
|
+
function getTypePathForTypeScript({ filePath }) {
|
|
244
|
+
return filePath.replace(/^.*\/src\//, 'src/').replace(/^.*\/test\//, 'test/');
|
|
245
|
+
}
|
|
246
|
+
function getTypePathLink(elem, prefix = doc_files_1.RemoteFlowrFilePathBaseRef) {
|
|
247
|
+
const fromSource = getTypePathForTypeScript(elem);
|
|
248
|
+
return `${prefix}/${fromSource}#L${elem.lineNumber}`;
|
|
225
249
|
}
|
|
226
250
|
function generateMermaidClassDiagram(hierarchyList, rootName, options, visited = new Set()) {
|
|
227
251
|
const collect = { nodeLines: [], edgeLines: [] };
|
|
@@ -261,10 +285,10 @@ function generateMermaidClassDiagram(hierarchyList, rootName, options, visited =
|
|
|
261
285
|
}
|
|
262
286
|
else {
|
|
263
287
|
if (node.kind === 'type' || hierarchyList.find(h => h.name === baseType)?.kind === 'type') {
|
|
264
|
-
collect.edgeLines.push(`${
|
|
288
|
+
collect.edgeLines.push(`${dropGenericsFromTypeName(baseType)} .. ${node.name}`);
|
|
265
289
|
}
|
|
266
290
|
else {
|
|
267
|
-
collect.edgeLines.push(`${
|
|
291
|
+
collect.edgeLines.push(`${dropGenericsFromTypeName(baseType)} <|-- ${node.name}`);
|
|
268
292
|
}
|
|
269
293
|
const { nodeLines, edgeLines } = generateMermaidClassDiagram(hierarchyList, baseType, options, visited);
|
|
270
294
|
collect.nodeLines.push(...nodeLines);
|
|
@@ -275,7 +299,10 @@ function generateMermaidClassDiagram(hierarchyList, rootName, options, visited =
|
|
|
275
299
|
return collect;
|
|
276
300
|
}
|
|
277
301
|
function visualizeMermaidClassDiagram(hierarchyList, options) {
|
|
278
|
-
|
|
302
|
+
if (!options.typeNameForMermaid) {
|
|
303
|
+
return undefined;
|
|
304
|
+
}
|
|
305
|
+
const { nodeLines, edgeLines } = generateMermaidClassDiagram(hierarchyList, options.typeNameForMermaid, options);
|
|
279
306
|
return nodeLines.length === 0 && edgeLines.length === 0 ? '' : `
|
|
280
307
|
classDiagram
|
|
281
308
|
direction RL
|
|
@@ -284,17 +311,20 @@ ${edgeLines.join('\n')}
|
|
|
284
311
|
`;
|
|
285
312
|
}
|
|
286
313
|
function getTypesFromFileAsMermaid(fileNames, options) {
|
|
287
|
-
const { files, program } =
|
|
314
|
+
const { files, program } = getTypeScriptSourceFiles(fileNames);
|
|
288
315
|
(0, assert_1.guard)(files.length > 0, () => `No source files found for ${JSON.stringify(fileNames)}`);
|
|
289
316
|
const withProgram = { ...options, program };
|
|
290
317
|
const hierarchyList = collectHierarchyInformation(files, withProgram);
|
|
291
318
|
return {
|
|
292
|
-
|
|
319
|
+
mermaid: visualizeMermaidClassDiagram(hierarchyList, withProgram),
|
|
293
320
|
info: hierarchyList,
|
|
294
321
|
program
|
|
295
322
|
};
|
|
296
323
|
}
|
|
297
|
-
|
|
324
|
+
/**
|
|
325
|
+
* Inspect typescript source code for types and return a report.
|
|
326
|
+
*/
|
|
327
|
+
function getTypesFromFolder(options) {
|
|
298
328
|
(0, assert_1.guard)(options.rootFolder !== undefined || options.files !== undefined, 'Either rootFolder or files must be provided');
|
|
299
329
|
const files = [...options.files ?? []];
|
|
300
330
|
if (options.rootFolder) {
|
|
@@ -356,17 +386,22 @@ function printCodeOfElement({ program, info }, name) {
|
|
|
356
386
|
const code = node.node.getFullText(program.getSourceFile(node.node.getSourceFile().fileName));
|
|
357
387
|
return `${(0, doc_code_1.codeBlock)('ts', code)}\n<i>Defined at <a href="${getTypePathLink(node)}">${getTypePathLink(node, '.')}</a></i>\n`;
|
|
358
388
|
}
|
|
359
|
-
function
|
|
389
|
+
function fuzzyCompare(a, b) {
|
|
390
|
+
const aStr = a.toLowerCase().replace(/[^a-z0-9]/g, '-').trim();
|
|
391
|
+
const bStr = b.toLowerCase().replace(/[^a-z0-9]/g, '-').trim();
|
|
392
|
+
return aStr === bStr || aStr.includes(bStr) || bStr.includes(aStr);
|
|
393
|
+
}
|
|
394
|
+
function retrieveNode(name, hierarchy, fuzzy = false) {
|
|
360
395
|
let container = undefined;
|
|
361
396
|
if (name.includes('::')) {
|
|
362
397
|
[container, name] = name.split(/:::?/);
|
|
363
398
|
}
|
|
364
|
-
let node = hierarchy.filter(e => e.name === name);
|
|
399
|
+
let node = hierarchy.filter(e => fuzzy ? fuzzyCompare(e.name, name) : e.name === name);
|
|
365
400
|
if (node.length === 0) {
|
|
366
401
|
return undefined;
|
|
367
402
|
}
|
|
368
403
|
else if (container) {
|
|
369
|
-
node = node.filter(n => n.extends.includes(container));
|
|
404
|
+
node = node.filter(n => fuzzy ? n.extends.some(n => fuzzyCompare(n, container)) : n.extends.includes(container));
|
|
370
405
|
if (node.length === 0) {
|
|
371
406
|
return undefined;
|
|
372
407
|
}
|
|
@@ -393,11 +428,20 @@ function shortLink(name, hierarchy, codeStyle = true, realNameWrapper = 'b') {
|
|
|
393
428
|
pkg = undefined;
|
|
394
429
|
}
|
|
395
430
|
const comments = node.comments?.join('\n').replace(/\\?\n|```[a-zA-Z]*|\s\s*/g, ' ').replace(/<\/?code>|`/g, '').replace(/<\/?p\/?>/g, ' ').replace(/"/g, '\'') ?? '';
|
|
396
|
-
return
|
|
397
|
-
(0, html_hover_over_1.textWithTooltip)(pkg ? `${pkg}::<${realNameWrapper}>${mainName}</${realNameWrapper}>` : mainName, comments.length > 400 ? comments.slice(0, 400) + '...' : comments) : node.name}${codeStyle ? '</code>' : ''}
|
|
431
|
+
return `<a href="${getTypePathLink(node)}">${codeStyle ? '<code>' : ''}${(node.comments?.length ?? 0) > 0 ?
|
|
432
|
+
(0, html_hover_over_1.textWithTooltip)(pkg ? `${pkg}::<${realNameWrapper}>${mainName}</${realNameWrapper}>` : mainName, comments.length > 400 ? comments.slice(0, 400) + '...' : comments) : node.name}${codeStyle ? '</code>' : ''}</a>`;
|
|
398
433
|
}
|
|
399
|
-
function
|
|
434
|
+
function shortLinkFile(name, hierarchy) {
|
|
400
435
|
const res = retrieveNode(name, hierarchy);
|
|
436
|
+
if (!res) {
|
|
437
|
+
console.error(`Could not find node ${name} when resolving short link!`);
|
|
438
|
+
return '';
|
|
439
|
+
}
|
|
440
|
+
const [, , node] = res;
|
|
441
|
+
return `<a href="${getTypePathLink(node)}">${getTypePathForTypeScript(node)}</a>`;
|
|
442
|
+
}
|
|
443
|
+
function getDocumentationForType(name, hierarchy, prefix = '', fuzzy = false) {
|
|
444
|
+
const res = retrieveNode(name, hierarchy, fuzzy);
|
|
401
445
|
if (!res) {
|
|
402
446
|
return '';
|
|
403
447
|
}
|
|
@@ -32,6 +32,7 @@ const semantic_cfg_guided_visitor_1 = require("../control-flow/semantic-cfg-guid
|
|
|
32
32
|
const doc_issue_1 = require("./doc-util/doc-issue");
|
|
33
33
|
const edge_1 = require("../dataflow/graph/edge");
|
|
34
34
|
const assert_1 = require("../util/assert");
|
|
35
|
+
const config_1 = require("../config");
|
|
35
36
|
const CfgLongExample = `f <- function(a, b = 3) {
|
|
36
37
|
if(a > b) {
|
|
37
38
|
return(a * b);
|
|
@@ -89,10 +90,10 @@ class CollectNumbersSyntaxVisitor extends syntax_cfg_guided_visitor_1.SyntaxAwar
|
|
|
89
90
|
class CollectNumbersDataflowVisitor extends dfg_cfg_guided_visitor_1.DataflowAwareCfgGuidedVisitor {
|
|
90
91
|
numbers = [];
|
|
91
92
|
constructor(controlFlow, dataflow) {
|
|
92
|
-
super({ controlFlow, dataflow, defaultVisitingOrder: 'forward' });
|
|
93
|
+
super({ controlFlow, dfg: dataflow, defaultVisitingOrder: 'forward' });
|
|
93
94
|
}
|
|
94
95
|
visitValue(node) {
|
|
95
|
-
const astNode = this.config.
|
|
96
|
+
const astNode = this.config.dfg.idMap?.get(node.id);
|
|
96
97
|
if ((0, r_number_1.isRNumber)(astNode)) {
|
|
97
98
|
this.numbers.push(astNode.content);
|
|
98
99
|
}
|
|
@@ -103,8 +104,8 @@ class CollectNumbersDataflowVisitor extends dfg_cfg_guided_visitor_1.DataflowAwa
|
|
|
103
104
|
}
|
|
104
105
|
class CollectSourcesSemanticVisitor extends semantic_cfg_guided_visitor_1.SemanticCfgGuidedVisitor {
|
|
105
106
|
sources = [];
|
|
106
|
-
constructor(controlFlow, normalizedAst, dataflow) {
|
|
107
|
-
super({ controlFlow, normalizedAst, dataflow, defaultVisitingOrder: 'forward' });
|
|
107
|
+
constructor(controlFlow, normalizedAst, dataflow, config) {
|
|
108
|
+
super({ controlFlow, normalizedAst, dfg: dataflow, flowrConfig: config, defaultVisitingOrder: 'forward' });
|
|
108
109
|
}
|
|
109
110
|
onAssignmentCall({ source }) {
|
|
110
111
|
if (source) {
|
|
@@ -117,14 +118,12 @@ class CollectSourcesSemanticVisitor extends semantic_cfg_guided_visitor_1.Semant
|
|
|
117
118
|
}
|
|
118
119
|
async function getText(shell) {
|
|
119
120
|
const rversion = (await shell.usedRVersion())?.format() ?? 'unknown';
|
|
120
|
-
const types = (0, doc_types_1.
|
|
121
|
+
const types = (0, doc_types_1.getTypesFromFolder)({
|
|
121
122
|
rootFolder: path_1.default.resolve('./src'),
|
|
122
|
-
typeName: 'RNode',
|
|
123
123
|
inlineTypes: doc_types_1.mermaidHide
|
|
124
124
|
});
|
|
125
|
-
const testTypes = (0, doc_types_1.
|
|
125
|
+
const testTypes = (0, doc_types_1.getTypesFromFolder)({
|
|
126
126
|
rootFolder: path_1.default.resolve('./test'),
|
|
127
|
-
typeName: 'assertCfg',
|
|
128
127
|
inlineTypes: doc_types_1.mermaidHide
|
|
129
128
|
});
|
|
130
129
|
return `${(0, doc_auto_gen_1.autoGenHeader)({ filename: module.filename, purpose: 'control flow graph', rVersion: rversion })}
|
|
@@ -206,7 +205,7 @@ ${(0, doc_structure_1.section)('Structure of the Control Flow Graph', 2, 'cfg-st
|
|
|
206
205
|
You can produce your very own control flow graph with ${(0, doc_types_1.shortLink)(extract_cfg_1.extractCfg.name, types.info)}.
|
|
207
206
|
The ${(0, doc_types_1.shortLink)(control_flow_graph_1.ControlFlowGraph.name, types.info)} class describes everything required to model the control flow graph, with its edge types described by
|
|
208
207
|
${(0, doc_types_1.shortLink)('CfgEdge', types.info)} and its vertices by ${(0, doc_types_1.shortLink)('CfgSimpleVertex', types.info)}.
|
|
209
|
-
However, you should be aware of the ${(0, doc_types_1.shortLink)('ControlFlowInformation', types.info)} interface which adds some additional information the
|
|
208
|
+
However, you should be aware of the ${(0, doc_types_1.shortLink)('ControlFlowInformation', types.info)} interface which adds some additional information the CFG
|
|
210
209
|
(and is used during the construction of the CFG as well):
|
|
211
210
|
|
|
212
211
|
${(0, doc_types_1.printHierarchy)({ info: types.info, root: 'ControlFlowInformation', program: types.program, openTop: true })}
|
|
@@ -475,7 +474,7 @@ Again, executing it with the CFG and Dataflow of the expression \`x - 1 + 2L * 3
|
|
|
475
474
|
|
|
476
475
|
${await (async () => {
|
|
477
476
|
const res = await (0, doc_cfg_1.getCfg)(shell, 'x - 1 + 2L * 3');
|
|
478
|
-
const visitor = new CollectNumbersDataflowVisitor(res.info, res.dataflow);
|
|
477
|
+
const visitor = new CollectNumbersDataflowVisitor(res.info, res.dataflow.graph);
|
|
479
478
|
visitor.start();
|
|
480
479
|
const collected = visitor.getNumbers();
|
|
481
480
|
return collected.map(n => '\n- `' + JSON.stringify(n) + '`').join('');
|
|
@@ -500,7 +499,7 @@ Executing it with the CFG and Dataflow of the expression \`x <- 2; 3 -> x; assig
|
|
|
500
499
|
|
|
501
500
|
${await (async () => {
|
|
502
501
|
const res = await (0, doc_cfg_1.getCfg)(shell, 'x <- 2; 3 -> x; assign("x", 42 + 21)');
|
|
503
|
-
const visitor = new CollectSourcesSemanticVisitor(res.info, res.ast, res.dataflow);
|
|
502
|
+
const visitor = new CollectSourcesSemanticVisitor(res.info, res.ast, res.dataflow.graph, config_1.defaultConfigOptions);
|
|
504
503
|
visitor.start();
|
|
505
504
|
const collected = visitor.getSources();
|
|
506
505
|
return collected.map(n => '\n- `' + n + '`').join('');
|
|
@@ -42,12 +42,12 @@ const normalize_for_1 = require("../r-bridge/lang-4.x/ast/parser/main/internal/l
|
|
|
42
42
|
const doc_issue_1 = require("./doc-util/doc-issue");
|
|
43
43
|
const pipeline_executor_1 = require("../core/pipeline-executor");
|
|
44
44
|
const pipeline_1 = require("../core/steps/pipeline/pipeline");
|
|
45
|
+
const config_1 = require("../config");
|
|
45
46
|
async function getText(shell) {
|
|
46
47
|
const rversion = (await shell.usedRVersion())?.format() ?? 'unknown';
|
|
47
48
|
const sampleCode = 'x <- 1; print(x)';
|
|
48
|
-
const { info, program } = (0, doc_types_1.
|
|
49
|
+
const { info, program } = (0, doc_types_1.getTypesFromFolder)({
|
|
49
50
|
rootFolder: path_1.default.resolve('./src'),
|
|
50
|
-
typeName: shell_1.RShell.name,
|
|
51
51
|
inlineTypes: doc_types_1.mermaidHide
|
|
52
52
|
});
|
|
53
53
|
return `${(0, doc_auto_gen_1.autoGenHeader)({ filename: module.filename, purpose: 'core', rVersion: rversion })}
|
|
@@ -112,7 +112,7 @@ const result = await executor.allRemainingSteps();
|
|
|
112
112
|
`)}
|
|
113
113
|
|
|
114
114
|
This is, roughly, what the ${(0, doc_types_1.shortLink)('replGetDataflow', info)} function does for the ${(0, doc_cli_option_1.getReplCommand)('dataflow')} REPL command when using the [\`tree-sitter\` engine](${doc_files_1.FlowrWikiBaseRef}/Engines).
|
|
115
|
-
We create a new ${(0, doc_types_1.shortLink)(pipeline_executor_1.PipelineExecutor.name, info)} with the ${(0, doc_types_1.shortLink)('TREE_SITTER_DATAFLOW_PIPELINE', info)} and then use ${(0, doc_types_1.shortLink)(`${pipeline_executor_1.PipelineExecutor.name}::${new pipeline_executor_1.PipelineExecutor(default_pipelines_1.TREE_SITTER_PARSE_PIPELINE, { parser: new tree_sitter_executor_1.TreeSitterExecutor(), request: (0, retriever_1.requestFromInput)('') }).allRemainingSteps.name}`, info)}
|
|
115
|
+
We create a new ${(0, doc_types_1.shortLink)(pipeline_executor_1.PipelineExecutor.name, info)} with the ${(0, doc_types_1.shortLink)('TREE_SITTER_DATAFLOW_PIPELINE', info)} and then use ${(0, doc_types_1.shortLink)(`${pipeline_executor_1.PipelineExecutor.name}::${new pipeline_executor_1.PipelineExecutor(default_pipelines_1.TREE_SITTER_PARSE_PIPELINE, { parser: new tree_sitter_executor_1.TreeSitterExecutor(), request: (0, retriever_1.requestFromInput)('') }, config_1.defaultConfigOptions).allRemainingSteps.name}`, info)}
|
|
116
116
|
to cause the execution of all contained steps (in general, pipelines can be executed step-by-step, but this is usually not required if you just want the result).
|
|
117
117
|
${(0, doc_types_1.shortLink)(retriever_1.requestFromInput.name, info)} is merely a convenience function to create a request object from a code string.
|
|
118
118
|
|
|
@@ -254,7 +254,7 @@ While looking at the mermaid visualization of such an AST is nice and usually su
|
|
|
254
254
|
|
|
255
255
|
Let's have a look at the normalized AST for the sample code \`${sampleCode}\` (please refer to the [normalized AST](${doc_files_1.FlowrWikiBaseRef}/Normalized-AST) wiki page for more information):
|
|
256
256
|
|
|
257
|
-
${(0, doc_structure_1.details)('Normalized AST for <code>x <- 1; print(x)</code>', (0, doc_code_1.codeBlock)('json', JSON.stringify((await (0, default_pipelines_1.createNormalizePipeline)(shell, { request: (0, retriever_1.requestFromInput)(sampleCode) }).allRemainingSteps()).normalize.ast, json_1.jsonReplacer, 4)))}
|
|
257
|
+
${(0, doc_structure_1.details)('Normalized AST for <code>x <- 1; print(x)</code>', (0, doc_code_1.codeBlock)('json', JSON.stringify((await (0, default_pipelines_1.createNormalizePipeline)(shell, { request: (0, retriever_1.requestFromInput)(sampleCode) }, config_1.defaultConfigOptions).allRemainingSteps()).normalize.ast, json_1.jsonReplacer, 4)))}
|
|
258
258
|
|
|
259
259
|
This is… a lot! We get the type from the ${(0, doc_types_1.shortLink)('RType', info)} enum, the lexeme, location information, an id, the children of the node, and their parents.
|
|
260
260
|
While the [normalized AST](${doc_files_1.FlowrWikiBaseRef}/Normalized-AST) wiki page provides you with information on how to interpret this data, we will focus on how we get it from the
|
|
@@ -275,7 +275,7 @@ For single nodes, we use ${(0, doc_types_1.shortLink)(normalize_single_node_1.no
|
|
|
275
275
|
|
|
276
276
|
The output of just this pass is listed below (using the ${(0, doc_types_1.shortLink)(parser_2.normalizeButNotDecorated.name, info)} function):
|
|
277
277
|
|
|
278
|
-
${(0, doc_structure_1.details)('Ast for <code>x <- 1; print(x)</code> after the first normalization', (0, doc_code_1.codeBlock)('json', JSON.stringify((0, parser_2.normalizeButNotDecorated)((await (0, default_pipelines_1.createParsePipeline)(shell, { request: (0, retriever_1.requestFromInput)(sampleCode) }).allRemainingSteps()).parse), json_1.jsonReplacer, 4)))}
|
|
278
|
+
${(0, doc_structure_1.details)('Ast for <code>x <- 1; print(x)</code> after the first normalization', (0, doc_code_1.codeBlock)('json', JSON.stringify((0, parser_2.normalizeButNotDecorated)((await (0, default_pipelines_1.createParsePipeline)(shell, { request: (0, retriever_1.requestFromInput)(sampleCode) }, config_1.defaultConfigOptions).allRemainingSteps()).parse), json_1.jsonReplacer, 4)))}
|
|
279
279
|
|
|
280
280
|
|
|
281
281
|
#### Decorating the AST
|
|
@@ -34,9 +34,11 @@ const linker_1 = require("../dataflow/internal/linker");
|
|
|
34
34
|
const doc_normalized_ast_1 = require("./doc-util/doc-normalized-ast");
|
|
35
35
|
const dfg_get_origin_1 = require("../dataflow/origin/dfg-get-origin");
|
|
36
36
|
const identify_link_to_last_call_relation_1 = require("../queries/catalog/call-context-query/identify-link-to-last-call-relation");
|
|
37
|
+
const alias_tracking_1 = require("../dataflow/eval/resolve/alias-tracking");
|
|
37
38
|
const doc_issue_1 = require("./doc-util/doc-issue");
|
|
38
39
|
const unnamed_call_handling_1 = require("../dataflow/internal/process/functions/call/unnamed-call-handling");
|
|
39
40
|
const environment_builder_1 = require("../../test/functionality/_helper/dataflow/environment-builder");
|
|
41
|
+
const config_1 = require("../config");
|
|
40
42
|
async function subExplanation(shell, { description, code, expectedSubgraph }) {
|
|
41
43
|
expectedSubgraph = await (0, doc_dfg_1.verifyExpectedSubgraph)(shell, code, expectedSubgraph);
|
|
42
44
|
const marks = [];
|
|
@@ -203,9 +205,8 @@ ${(0, doc_structure_1.details)('Example: Simple Function Call (unresolved)', awa
|
|
|
203
205
|
(0, assert_1.guard)(callInfo !== undefined, () => `Could not find call vertex for ${code}`);
|
|
204
206
|
const [callId, callVert] = callInfo;
|
|
205
207
|
const inverseMapReferenceTypes = Object.fromEntries(Object.entries(identifier_1.ReferenceType).map(([k, v]) => [v, k]));
|
|
206
|
-
const identifierType = (0, doc_types_1.
|
|
208
|
+
const identifierType = (0, doc_types_1.getTypesFromFolder)({
|
|
207
209
|
files: [path_1.default.resolve('./src/dataflow/environments/identifier.ts')],
|
|
208
|
-
typeName: 'IdentifierReference',
|
|
209
210
|
inlineTypes: ['ControlDependency']
|
|
210
211
|
});
|
|
211
212
|
return `
|
|
@@ -744,21 +745,21 @@ async function dummyDataflow() {
|
|
|
744
745
|
const result = await new pipeline_executor_1.PipelineExecutor(default_pipelines_1.DEFAULT_DATAFLOW_PIPELINE, {
|
|
745
746
|
parser: shell,
|
|
746
747
|
request: (0, retriever_1.requestFromInput)('x <- 1\nx + 1')
|
|
747
|
-
}).allRemainingSteps();
|
|
748
|
+
}, config_1.defaultConfigOptions).allRemainingSteps();
|
|
748
749
|
shell.close();
|
|
749
750
|
return result;
|
|
750
751
|
}
|
|
751
752
|
async function getText(shell) {
|
|
752
753
|
const rversion = (await shell.usedRVersion())?.format() ?? 'unknown';
|
|
753
754
|
/* we collect type information on the graph */
|
|
754
|
-
const vertexType = (0, doc_types_1.
|
|
755
|
+
const vertexType = (0, doc_types_1.getTypesFromFolder)({
|
|
755
756
|
rootFolder: path_1.default.resolve('./src/'),
|
|
756
|
-
|
|
757
|
+
typeNameForMermaid: 'DataflowGraphVertexInfo',
|
|
757
758
|
inlineTypes: ['MergeableRecord']
|
|
758
759
|
});
|
|
759
|
-
const edgeType = (0, doc_types_1.
|
|
760
|
+
const edgeType = (0, doc_types_1.getTypesFromFolder)({
|
|
760
761
|
files: [path_1.default.resolve('./src/dataflow/graph/edge.ts'), path_1.default.resolve('./src/dataflow/graph/graph.ts'), path_1.default.resolve('./src/dataflow/environments/identifier.ts'), path_1.default.resolve('./src/dataflow/info.ts')],
|
|
761
|
-
|
|
762
|
+
typeNameForMermaid: 'EdgeType',
|
|
762
763
|
inlineTypes: ['MergeableRecord']
|
|
763
764
|
});
|
|
764
765
|
return `${(0, doc_auto_gen_1.autoGenHeader)({ filename: module.filename, purpose: 'dataflow graph', rVersion: rversion })}
|
|
@@ -806,7 +807,7 @@ The following vertices types exist:
|
|
|
806
807
|
|
|
807
808
|
1. ${(0, doc_data_dfg_util_1.getAllVertices)().map(([k, v], index) => `[\`${k}\`](#${index + 1}-${v.toLowerCase().replace(/\s/g, '-')}-vertex)`).join('\n1. ')}
|
|
808
809
|
|
|
809
|
-
${vertexType.
|
|
810
|
+
${vertexType.mermaid.trim().length > 0 ? (0, doc_structure_1.details)('Class Diagram', 'All boxes should link to their respective implementation:\n' + (0, doc_code_1.codeBlock)('mermaid', vertexType.mermaid)) : ''}
|
|
810
811
|
|
|
811
812
|
</details>
|
|
812
813
|
|
|
@@ -818,7 +819,7 @@ The following edges types exist, internally we use bitmasks to represent multipl
|
|
|
818
819
|
|
|
819
820
|
1. ${(0, doc_data_dfg_util_1.getAllEdges)().map(([k, v], index) => `[\`${k}\` (${v})](#${index + 1}-${k.toLowerCase().replace(/\s/g, '-')}-edge)`).join('\n1. ')}
|
|
820
821
|
|
|
821
|
-
${edgeType.
|
|
822
|
+
${edgeType.mermaid.trim().length > 0 ? (0, doc_structure_1.details)('Class Diagram', 'All boxes should link to their respective implementation:\n' + (0, doc_code_1.codeBlock)('mermaid', edgeType.mermaid)) : ''}
|
|
822
823
|
|
|
823
824
|
</details>
|
|
824
825
|
|
|
@@ -977,7 +978,7 @@ Depending on what you are interested in, there exists a plethora of functions an
|
|
|
977
978
|
* The **[Query API](${doc_files_1.FlowrWikiBaseRef}/Query%20API)** provides many functions to query the dataflow graph for specific information (dependencies, calls, slices, clusters, ...)
|
|
978
979
|
* The **[Search API](${doc_files_1.FlowrWikiBaseRef}/Search%20API)** allows you to search for specific vertices or edges in the dataflow graph or the original program
|
|
979
980
|
* ${(0, doc_types_1.shortLink)(node_id_1.recoverName.name, vertexType.info)} and ${(0, doc_types_1.shortLink)(node_id_1.recoverContent.name, vertexType.info)} to get the name or content of a vertex in the dataflow graph
|
|
980
|
-
* ${(0, doc_types_1.shortLink)(
|
|
981
|
+
* ${(0, doc_types_1.shortLink)(alias_tracking_1.resolveIdToValue.name, vertexType.info)} to resolve the value of a variable or id (if possible, see [below](#dfg-resolving-values))
|
|
981
982
|
* ${(0, doc_types_1.shortLink)(edge_1.edgeIncludesType.name, vertexType.info)} to check if an edge includes a specific type and ${(0, doc_types_1.shortLink)(edge_1.splitEdgeTypes.name, vertexType.info)} to split the bitmask of edges into its types (see [below](#dfg-resolving-values))
|
|
982
983
|
* ${(0, doc_types_1.shortLink)(identify_link_to_last_call_relation_1.getValueOfArgument.name, vertexType.info)} to get the (syntactical) value of an argument in a function call
|
|
983
984
|
* ${(0, doc_types_1.shortLink)(dfg_get_origin_1.getOriginInDfg.name, vertexType.info)} to get information about where a read, call, ... comes from (see [below](#dfg-resolving-values))
|
|
@@ -989,8 +990,8 @@ ${(0, doc_structure_1.section)('Resolving Values', 3, 'dfg-resolving-values')}
|
|
|
989
990
|
FlowR supports a [configurable](${doc_files_1.FlowrWikiBaseRef}/Interface#configuring-flowr) level of value tracking—all with the goal of knowing the static value domain of a variable.
|
|
990
991
|
These capabilities are exposed by the [resolve value Query](${doc_files_1.FlowrWikiBaseRef}/Query-API#resolve-value-query) and backed by two important functions:
|
|
991
992
|
|
|
992
|
-
${(0, doc_types_1.shortLink)(
|
|
993
|
-
value resolution
|
|
993
|
+
${(0, doc_types_1.shortLink)(alias_tracking_1.resolveIdToValue.name, vertexType.info)} provides an environment-sensitive (see ${(0, doc_types_1.shortLink)('REnvironmentInformation', vertexType.info)})
|
|
994
|
+
value resolution depending on if the environment is provided.
|
|
994
995
|
|
|
995
996
|
${(0, doc_structure_1.section)('Assessing Edges', 3, 'dfg-assess-edge')}
|
|
996
997
|
|
|
@@ -1004,7 +1005,7 @@ Retrieving the _types_ of the edge from the print call to its argument returns:
|
|
|
1004
1005
|
${await (async () => {
|
|
1005
1006
|
const dfg = await (0, default_pipelines_1.createDataflowPipeline)(shell, {
|
|
1006
1007
|
request: (0, retriever_1.requestFromInput)('print(x)')
|
|
1007
|
-
}).allRemainingSteps();
|
|
1008
|
+
}, config_1.defaultConfigOptions).allRemainingSteps();
|
|
1008
1009
|
const edge = dfg.dataflow.graph.outgoingEdges(3);
|
|
1009
1010
|
if (edge) {
|
|
1010
1011
|
const wanted = edge.get(1);
|
|
@@ -15,10 +15,9 @@ const doc_cli_option_1 = require("./doc-util/doc-cli-option");
|
|
|
15
15
|
const doc_structure_1 = require("./doc-util/doc-structure");
|
|
16
16
|
async function getText(shell) {
|
|
17
17
|
const rversion = (await shell.usedRVersion())?.format() ?? 'unknown';
|
|
18
|
-
const types = (0, doc_types_1.
|
|
18
|
+
const types = (0, doc_types_1.getTypesFromFolder)({
|
|
19
19
|
rootFolder: path_1.default.resolve('src/r-bridge/lang-4.x/tree-sitter/'),
|
|
20
20
|
files: [path_1.default.resolve('./src/config.ts'), path_1.default.resolve('./src/r-bridge/shell.ts'), path_1.default.resolve('./src/r-bridge/shell-executor.ts')],
|
|
21
|
-
typeName: 'FlowrConfigOptions',
|
|
22
21
|
inlineTypes: doc_types_1.mermaidHide
|
|
23
22
|
});
|
|
24
23
|
return `${(0, doc_auto_gen_1.autoGenHeader)({ filename: module.filename, purpose: 'engines', rVersion: rversion })}
|
|
@@ -49,7 +48,7 @@ are exposed with some command line options (e.g., when using the docker image of
|
|
|
49
48
|
|
|
50
49
|
${(0, doc_structure_1.block)({
|
|
51
50
|
type: 'WARNING',
|
|
52
|
-
content: 'As the tree-sitter engine is only for parsing, it cannot execute R code.'
|
|
51
|
+
content: 'As the tree-sitter engine is only for parsing, it cannot execute R code. This engine is now the default.'
|
|
53
52
|
})}
|
|
54
53
|
|
|
55
54
|
In general, there is no need for you to pass custom paths using either
|
|
@@ -24,14 +24,20 @@ There are several ways to generate mermaid diagrams based on the input data that
|
|
|
24
24
|
|
|
25
25
|
${qAndA('How do I create new wiki pages?', `
|
|
26
26
|
To create an automatically generated wiki page, you can follow these steps:
|
|
27
|
-
-
|
|
27
|
+
- Create a new file in \`src/documentation\` with a name like \`print-my-page-wiki.ts\`.
|
|
28
28
|
- Add a new wiki generation script to the ${(0, doc_files_1.getFilePathMd)('../../package.json')}. You can copy one of the existing ones of the form \`"wiki:my-page": "ts-node src/documentation/print-my-page-wiki.ts"\`.
|
|
29
29
|
- Add the wiki generation script to the \`broken-links-and-wiki.yml\` GitHub workflow file to enable automatic generation through the CI. You can copy one of the existing ones of the form \`update_page wiki/"My page" wiki:my-page\`.
|
|
30
30
|
|
|
31
31
|
You can test your page by piping the wiki generation script to a file. For example, you can run the following command:
|
|
32
32
|
${(0, doc_code_1.codeBlock)('shell', 'npm run --silent wiki:my-page > __my-page.md')}
|
|
33
|
-
|
|
33
|
+
|
|
34
34
|
Remember not to commit this file, as it's only meant for testing.
|
|
35
|
+
`)}
|
|
36
|
+
|
|
37
|
+
${qAndA('Why can\'t I pass arguments when running flowR with npm?', `
|
|
38
|
+
With \`npm\` you have to pass arguments in a specific way. The \`--\` operator is used to separate the \`npm\` arguments from the script arguments. For example, if you want to run \`flowR\` with the \`--help\` argument, you can use the following command:
|
|
39
|
+
${(0, doc_code_1.codeBlock)('shell', 'npm run flowR -- --help')}
|
|
40
|
+
`)}
|
|
35
41
|
|
|
36
42
|
## 🇷 R FAQ
|
|
37
43
|
|
|
@@ -249,10 +249,9 @@ ${(0, schema_1.describeSchema)(config_1.flowrConfigFileSchema, ansi_1.markdownFo
|
|
|
249
249
|
`;
|
|
250
250
|
}
|
|
251
251
|
function explainWritingCode(shell) {
|
|
252
|
-
const types = (0, doc_types_1.
|
|
252
|
+
const types = (0, doc_types_1.getTypesFromFolder)({
|
|
253
253
|
rootFolder: path_1.default.resolve('./src/'),
|
|
254
254
|
files: [path_1.default.resolve('./src/core/pipeline-executor.ts'), path_1.default.resolve('./src/core/steps/pipeline/default-pipelines.ts')],
|
|
255
|
-
typeName: 'RShell',
|
|
256
255
|
inlineTypes: doc_types_1.mermaidHide
|
|
257
256
|
});
|
|
258
257
|
return `
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|