@eagleoutice/flowr 2.2.11 → 2.2.13
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 +82 -20
- package/benchmark/slicer.d.ts +49 -22
- package/benchmark/slicer.js +89 -29
- package/benchmark/stats/print.js +16 -10
- package/benchmark/stats/size-of.js +18 -1
- package/benchmark/stats/stats.d.ts +3 -0
- package/benchmark/summarizer/first-phase/input.js +1 -1
- package/benchmark/summarizer/first-phase/process.js +3 -3
- package/benchmark/summarizer/second-phase/process.js +9 -3
- package/benchmark/summarizer/summarizer.js +1 -1
- package/cli/benchmark-app.d.ts +5 -0
- package/cli/benchmark-app.js +49 -6
- package/cli/benchmark-helper-app.d.ts +4 -0
- package/cli/benchmark-helper-app.js +20 -4
- package/cli/common/options.js +15 -6
- package/cli/common/script.js +1 -1
- package/cli/flowr.js +1 -1
- package/cli/repl/commands/repl-cfg.d.ts +2 -0
- package/cli/repl/commands/repl-cfg.js +38 -24
- package/cli/repl/commands/repl-commands.js +6 -2
- package/cli/repl/commands/repl-dataflow.d.ts +2 -0
- package/cli/repl/commands/repl-dataflow.js +37 -3
- package/cli/repl/commands/repl-execute.js +1 -1
- package/cli/repl/commands/repl-main.d.ts +1 -1
- package/cli/repl/commands/repl-main.js +1 -1
- package/cli/repl/commands/repl-normalize.js +1 -1
- package/cli/repl/commands/repl-query.js +2 -2
- package/cli/repl/core.js +1 -1
- package/cli/repl/prompt.js +1 -1
- package/cli/repl/server/connection.js +4 -4
- package/cli/repl/server/messages/message-analysis.d.ts +1 -1
- package/cli/script-core/statistics-core.js +1 -1
- package/cli/script-core/statistics-helper-core.js +4 -4
- package/config.d.ts +60 -21
- package/config.js +24 -4
- package/control-flow/basic-cfg-guided-visitor.d.ts +39 -0
- package/control-flow/basic-cfg-guided-visitor.js +114 -0
- package/control-flow/cfg-properties.d.ts +26 -0
- package/control-flow/cfg-properties.js +100 -0
- package/control-flow/cfg-simplification.d.ts +18 -0
- package/control-flow/cfg-simplification.js +55 -0
- package/control-flow/cfg-to-basic-blocks.d.ts +5 -0
- package/control-flow/cfg-to-basic-blocks.js +81 -0
- package/control-flow/control-flow-graph.d.ts +247 -0
- package/control-flow/control-flow-graph.js +290 -0
- package/control-flow/dfg-cfg-guided-visitor.d.ts +32 -0
- package/control-flow/dfg-cfg-guided-visitor.js +71 -0
- package/control-flow/diff-cfg.d.ts +11 -0
- package/control-flow/diff-cfg.js +161 -0
- package/control-flow/extract-cfg.d.ts +30 -0
- package/control-flow/extract-cfg.js +475 -0
- package/control-flow/happens-before.d.ts +7 -0
- package/{util/cfg → control-flow}/happens-before.js +3 -3
- package/control-flow/semantic-cfg-guided-visitor.d.ts +452 -0
- package/control-flow/semantic-cfg-guided-visitor.js +492 -0
- package/control-flow/simple-visitor.d.ts +25 -0
- package/control-flow/simple-visitor.js +80 -0
- package/control-flow/syntax-cfg-guided-visitor.d.ts +128 -0
- package/control-flow/syntax-cfg-guided-visitor.js +166 -0
- package/core/print/print.d.ts +1 -1
- package/core/print/slice-diff-ansi.js +1 -1
- package/core/steps/pipeline/create-pipeline.js +1 -1
- package/dataflow/environments/built-in-config.d.ts +5 -2
- package/dataflow/environments/built-in-config.js +17 -8
- package/dataflow/environments/built-in.d.ts +16 -5
- package/dataflow/environments/built-in.js +55 -6
- package/dataflow/environments/clone.d.ts +5 -0
- package/dataflow/environments/clone.js +5 -0
- package/dataflow/environments/default-builtin-config.d.ts +2 -0
- package/dataflow/environments/default-builtin-config.js +164 -13
- package/dataflow/environments/define.d.ts +5 -1
- package/dataflow/environments/define.js +36 -10
- package/dataflow/environments/overwrite.js +4 -0
- package/dataflow/environments/remove.d.ts +6 -0
- package/dataflow/environments/remove.js +24 -0
- package/dataflow/environments/resolve-by-name.js +16 -5
- package/dataflow/extractor.js +2 -2
- package/dataflow/graph/dataflowgraph-builder.d.ts +79 -7
- package/dataflow/graph/dataflowgraph-builder.js +106 -8
- package/dataflow/graph/diff-dataflow-graph.d.ts +16 -0
- package/dataflow/graph/{diff.js → diff-dataflow-graph.js} +30 -56
- package/dataflow/graph/graph.d.ts +17 -4
- package/dataflow/graph/graph.js +51 -12
- package/dataflow/graph/vertex.d.ts +59 -4
- package/dataflow/graph/vertex.js +32 -0
- package/dataflow/internal/linker.d.ts +3 -2
- package/dataflow/internal/linker.js +36 -25
- package/dataflow/internal/process/functions/call/argument/unpack-argument.d.ts +1 -1
- package/dataflow/internal/process/functions/call/argument/unpack-argument.js +1 -1
- package/dataflow/internal/process/functions/call/built-in/built-in-access.d.ts +1 -0
- package/dataflow/internal/process/functions/call/built-in/built-in-access.js +67 -54
- package/dataflow/internal/process/functions/call/built-in/built-in-apply.d.ts +6 -4
- package/dataflow/internal/process/functions/call/built-in/built-in-apply.js +108 -21
- package/dataflow/internal/process/functions/call/built-in/built-in-assignment.js +54 -17
- package/dataflow/internal/process/functions/call/built-in/built-in-eval.d.ts +10 -0
- package/dataflow/internal/process/functions/call/built-in/built-in-eval.js +140 -0
- package/dataflow/internal/process/functions/call/built-in/built-in-expression-list.js +9 -4
- package/dataflow/internal/process/functions/call/built-in/built-in-for-loop.js +3 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-function-definition.js +15 -4
- package/dataflow/internal/process/functions/call/built-in/built-in-get.js +4 -3
- package/dataflow/internal/process/functions/call/built-in/built-in-if-then-else.js +4 -3
- package/dataflow/internal/process/functions/call/built-in/built-in-library.js +4 -3
- package/dataflow/internal/process/functions/call/built-in/built-in-list.js +51 -17
- package/dataflow/internal/process/functions/call/built-in/built-in-pipe.js +1 -1
- package/dataflow/internal/process/functions/call/built-in/built-in-quote.js +9 -7
- package/dataflow/internal/process/functions/call/built-in/built-in-repeat-loop.js +3 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-replacement.d.ts +4 -0
- package/dataflow/internal/process/functions/call/built-in/built-in-replacement.js +100 -31
- package/dataflow/internal/process/functions/call/built-in/built-in-rm.d.ts +7 -0
- package/dataflow/internal/process/functions/call/built-in/built-in-rm.js +41 -0
- package/dataflow/internal/process/functions/call/built-in/built-in-source.js +35 -8
- package/dataflow/internal/process/functions/call/built-in/built-in-special-bin-op.js +4 -3
- package/dataflow/internal/process/functions/call/built-in/built-in-vector.d.ts +15 -0
- package/dataflow/internal/process/functions/call/built-in/built-in-vector.js +75 -0
- package/dataflow/internal/process/functions/call/built-in/built-in-while-loop.js +3 -3
- package/dataflow/internal/process/functions/call/common.d.ts +5 -2
- package/dataflow/internal/process/functions/call/common.js +9 -5
- package/dataflow/internal/process/functions/call/known-call-handling.d.ts +3 -2
- package/dataflow/internal/process/functions/call/known-call-handling.js +2 -1
- package/dataflow/internal/process/functions/call/named-call-handling.d.ts +2 -0
- package/dataflow/internal/process/functions/call/named-call-handling.js +10 -6
- package/dataflow/internal/process/functions/call/unnamed-call-handling.d.ts +1 -0
- package/dataflow/internal/process/functions/call/unnamed-call-handling.js +6 -4
- package/dataflow/internal/process/process-named-call.d.ts +4 -1
- package/dataflow/internal/process/process-named-call.js +8 -5
- package/dataflow/origin/dfg-get-origin.d.ts +82 -0
- package/dataflow/origin/dfg-get-origin.js +116 -0
- package/documentation/doc-util/doc-cfg.d.ts +20 -4
- package/documentation/doc-util/doc-cfg.js +41 -7
- package/documentation/doc-util/doc-cli-option.js +4 -2
- package/documentation/doc-util/doc-code.js +10 -2
- package/documentation/doc-util/doc-dfg.js +3 -3
- package/documentation/doc-util/doc-escape.d.ts +7 -0
- package/documentation/doc-util/doc-escape.js +19 -0
- package/documentation/doc-util/doc-files.d.ts +1 -0
- package/documentation/doc-util/doc-files.js +2 -1
- package/documentation/doc-util/doc-normalized-ast.js +3 -3
- package/documentation/doc-util/doc-query.js +2 -2
- package/documentation/doc-util/doc-repl.js +1 -1
- package/documentation/doc-util/doc-search.js +1 -1
- package/documentation/doc-util/doc-server-message.js +2 -2
- package/documentation/doc-util/doc-structure.d.ts +1 -0
- package/documentation/doc-util/doc-structure.js +5 -0
- package/documentation/doc-util/doc-types.d.ts +7 -1
- package/documentation/doc-util/doc-types.js +13 -2
- package/documentation/print-capabilities-markdown.js +28 -2
- package/documentation/print-cfg-wiki.d.ts +1 -0
- package/documentation/print-cfg-wiki.js +572 -0
- package/documentation/print-core-wiki.js +2 -2
- package/documentation/print-dataflow-graph-wiki.js +180 -25
- package/documentation/print-engines-wiki.js +1 -1
- package/documentation/print-faq-wiki.d.ts +1 -0
- package/documentation/print-faq-wiki.js +75 -0
- package/documentation/print-interface-wiki.js +2 -1
- package/documentation/print-linting-and-testing-wiki.js +52 -36
- package/documentation/print-normalized-ast-wiki.js +1 -1
- package/documentation/print-onboarding-wiki.d.ts +1 -0
- package/documentation/print-onboarding-wiki.js +42 -0
- package/documentation/print-query-wiki.js +23 -3
- package/documentation/print-readme.js +10 -3
- package/package.json +10 -6
- package/queries/catalog/call-context-query/call-context-query-executor.js +5 -5
- package/queries/catalog/call-context-query/call-context-query-format.d.ts +1 -1
- package/queries/catalog/call-context-query/call-context-query-format.js +2 -2
- package/queries/catalog/call-context-query/identify-link-to-last-call-relation.d.ts +2 -2
- package/queries/catalog/call-context-query/identify-link-to-last-call-relation.js +24 -21
- package/queries/catalog/cluster-query/cluster-query-format.d.ts +1 -1
- package/queries/catalog/cluster-query/cluster-query-format.js +1 -1
- package/queries/catalog/config-query/config-query-format.d.ts +1 -1
- package/queries/catalog/config-query/config-query-format.js +2 -2
- package/queries/catalog/dataflow-lens-query/dataflow-lens-query-format.d.ts +1 -1
- package/queries/catalog/dataflow-lens-query/dataflow-lens-query-format.js +2 -2
- package/queries/catalog/dataflow-query/dataflow-query-format.d.ts +1 -1
- package/queries/catalog/dataflow-query/dataflow-query-format.js +2 -2
- package/queries/catalog/dependencies-query/dependencies-query-executor.js +17 -7
- package/queries/catalog/dependencies-query/dependencies-query-format.d.ts +2 -26
- package/queries/catalog/dependencies-query/dependencies-query-format.js +4 -147
- package/queries/catalog/dependencies-query/function-info/function-info.d.ts +24 -0
- package/queries/catalog/dependencies-query/function-info/function-info.js +10 -0
- package/queries/catalog/dependencies-query/function-info/library-functions.d.ts +2 -0
- package/queries/catalog/dependencies-query/function-info/library-functions.js +18 -0
- package/queries/catalog/dependencies-query/function-info/read-functions.d.ts +2 -0
- package/queries/catalog/dependencies-query/function-info/read-functions.js +101 -0
- package/queries/catalog/dependencies-query/function-info/source-functions.d.ts +2 -0
- package/queries/catalog/dependencies-query/function-info/source-functions.js +11 -0
- package/queries/catalog/dependencies-query/function-info/write-functions.d.ts +2 -0
- package/queries/catalog/dependencies-query/function-info/write-functions.js +87 -0
- package/queries/catalog/happens-before-query/happens-before-query-executor.d.ts +1 -1
- package/queries/catalog/happens-before-query/happens-before-query-executor.js +4 -4
- package/queries/catalog/happens-before-query/happens-before-query-format.d.ts +1 -1
- package/queries/catalog/happens-before-query/happens-before-query-format.js +2 -2
- package/queries/catalog/id-map-query/id-map-query-format.d.ts +1 -1
- package/queries/catalog/id-map-query/id-map-query-format.js +2 -2
- package/queries/catalog/lineage-query/lineage-query-format.d.ts +1 -1
- package/queries/catalog/lineage-query/lineage-query-format.js +2 -2
- package/queries/catalog/location-map-query/location-map-query-format.d.ts +1 -1
- package/queries/catalog/location-map-query/location-map-query-format.js +2 -2
- package/queries/catalog/normalized-ast-query/normalized-ast-query-format.d.ts +1 -1
- package/queries/catalog/normalized-ast-query/normalized-ast-query-format.js +2 -2
- package/queries/catalog/origin-query/origin-query-executor.d.ts +5 -0
- package/queries/catalog/origin-query/origin-query-executor.js +33 -0
- package/queries/catalog/origin-query/origin-query-format.d.ts +71 -0
- package/queries/catalog/origin-query/origin-query-format.js +27 -0
- package/queries/catalog/project-query/project-query-format.d.ts +1 -1
- package/queries/catalog/project-query/project-query-format.js +2 -2
- package/queries/catalog/resolve-value-query/resolve-value-query-format.d.ts +1 -1
- package/queries/catalog/resolve-value-query/resolve-value-query-format.js +2 -2
- package/queries/catalog/search-query/search-query-format.d.ts +1 -1
- package/queries/catalog/search-query/search-query-format.js +2 -2
- package/queries/catalog/static-slice-query/static-slice-query-format.d.ts +1 -1
- package/queries/catalog/static-slice-query/static-slice-query-format.js +2 -2
- package/queries/query-print.d.ts +1 -1
- package/queries/query-print.js +4 -4
- package/queries/query.d.ts +61 -2
- package/queries/query.js +3 -1
- package/r-bridge/data/data.d.ts +2 -2
- package/r-bridge/data/data.js +2 -2
- package/r-bridge/lang-4.x/ast/model/nodes/r-number.d.ts +3 -2
- package/r-bridge/lang-4.x/ast/model/nodes/r-number.js +5 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-string.d.ts +3 -2
- package/r-bridge/lang-4.x/ast/model/nodes/r-string.js +5 -0
- package/r-bridge/lang-4.x/ast/model/processing/decorate.d.ts +1 -1
- package/r-bridge/lang-4.x/ast/model/processing/decorate.js +1 -1
- package/r-bridge/lang-4.x/ast/model/processing/fold.js +3 -1
- package/r-bridge/lang-4.x/ast/model/processing/stateful-fold.d.ts +1 -1
- package/r-bridge/lang-4.x/ast/parser/main/internal/expression/normalize-expression.js +1 -1
- package/r-bridge/lang-4.x/ast/parser/main/internal/functions/normalize-argument.js +1 -1
- package/r-bridge/lang-4.x/ast/parser/main/internal/functions/normalize-call.js +1 -1
- package/r-bridge/lang-4.x/ast/parser/main/internal/functions/normalize-definition.js +1 -1
- package/r-bridge/lang-4.x/ast/parser/main/internal/normalize-access.js +1 -1
- package/r-bridge/lang-4.x/ast/parser/main/internal/operators/normalize-binary.js +1 -1
- package/r-bridge/lang-4.x/ast/parser/main/internal/structure/normalize-root.js +1 -1
- package/r-bridge/lang-4.x/ast/parser/main/internal/values/normalize-symbol.js +1 -1
- package/r-bridge/lang-4.x/tree-sitter/tree-sitter-executor.d.ts +2 -2
- 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.js +26 -8
- package/r-bridge/retriever.js +1 -1
- package/search/search-executor/search-generators.d.ts +1 -1
- package/search/search-executor/search-transformer.d.ts +1 -1
- package/slicing/criterion/collect-all.js +1 -1
- package/slicing/static/slice-call.js +13 -3
- package/statistics/features/supported/assignments/post-process.js +1 -1
- package/statistics/features/supported/defined-functions/post-process.js +2 -2
- package/statistics/features/supported/used-functions/post-process.js +1 -1
- package/statistics/features/supported/used-packages/post-process.js +2 -2
- package/statistics/features/supported/values/post-process.js +2 -2
- package/statistics/output/print-stats.js +2 -2
- package/statistics/summarizer/post-process/clusterer.d.ts +1 -1
- package/statistics/summarizer/post-process/clusterer.js +1 -1
- package/statistics/summarizer/post-process/histogram.js +3 -3
- package/statistics/summarizer/post-process/post-process-output.js +3 -3
- package/statistics/summarizer/second-phase/process.js +2 -2
- package/statistics/summarizer/summarizer.js +2 -2
- package/util/assert.js +36 -1
- package/util/cfg/cfg.d.ts +0 -80
- package/util/cfg/cfg.js +0 -549
- package/util/{arrays.d.ts → collections/arrays.d.ts} +24 -1
- package/util/{arrays.js → collections/arrays.js} +44 -3
- package/util/collections/set.js +17 -0
- package/util/{list-access.d.ts → containers.d.ts} +24 -4
- package/util/{list-access.js → containers.js} +42 -12
- package/util/diff-graph.d.ts +47 -0
- package/util/diff-graph.js +61 -0
- package/util/diff.d.ts +6 -6
- package/util/diff.js +1 -1
- package/util/mermaid/ast.js +12 -1
- package/util/mermaid/cfg.d.ts +9 -2
- package/util/mermaid/cfg.js +65 -13
- package/util/mermaid/dfg.d.ts +2 -1
- package/util/mermaid/dfg.js +26 -10
- package/util/mermaid/mermaid.d.ts +2 -0
- package/util/mermaid/mermaid.js +6 -0
- package/util/parallel.d.ts +2 -1
- package/util/parallel.js +11 -2
- package/util/prefix.d.ts +13 -0
- package/util/prefix.js +34 -0
- package/util/quads.js +1 -1
- package/util/schema.d.ts +1 -1
- package/util/schema.js +1 -1
- package/util/summarizer.js +1 -1
- package/util/{text.js → text/text.js} +1 -1
- package/util/{time.js → text/time.js} +1 -1
- package/util/version.js +1 -1
- package/dataflow/graph/diff.d.ts +0 -36
- package/util/cfg/happens-before.d.ts +0 -7
- package/util/cfg/visitor.d.ts +0 -9
- package/util/cfg/visitor.js +0 -30
- package/util/set.js +0 -31
- /package/util/{bimap.d.ts → collections/bimap.d.ts} +0 -0
- /package/util/{bimap.js → collections/bimap.js} +0 -0
- /package/util/{defaultmap.d.ts → collections/defaultmap.d.ts} +0 -0
- /package/util/{defaultmap.js → collections/defaultmap.js} +0 -0
- /package/util/{set.d.ts → collections/set.d.ts} +0 -0
- /package/util/{ansi.d.ts → text/ansi.d.ts} +0 -0
- /package/util/{ansi.js → text/ansi.js} +0 -0
- /package/util/{args.d.ts → text/args.d.ts} +0 -0
- /package/util/{args.js → text/args.js} +0 -0
- /package/util/{strings.d.ts → text/strings.d.ts} +0 -0
- /package/util/{strings.js → text/strings.js} +0 -0
- /package/util/{text.d.ts → text/text.d.ts} +0 -0
- /package/util/{time.d.ts → text/time.d.ts} +0 -0
|
@@ -26,13 +26,17 @@ const node_id_1 = require("../r-bridge/lang-4.x/ast/model/processing/node-id");
|
|
|
26
26
|
const identifier_1 = require("../dataflow/environments/identifier");
|
|
27
27
|
const r_function_call_1 = require("../r-bridge/lang-4.x/ast/model/nodes/r-function-call");
|
|
28
28
|
const resolve_by_name_1 = require("../dataflow/environments/resolve-by-name");
|
|
29
|
-
const environment_builder_1 = require("../../test/functionality/_helper/dataflow/environment-builder");
|
|
30
29
|
const default_pipelines_1 = require("../core/steps/pipeline/default-pipelines");
|
|
31
30
|
const doc_auto_gen_1 = require("./doc-util/doc-auto-gen");
|
|
32
|
-
const text_1 = require("../util/text");
|
|
31
|
+
const text_1 = require("../util/text/text");
|
|
33
32
|
const log_1 = require("../../test/functionality/_helper/log");
|
|
34
33
|
const linker_1 = require("../dataflow/internal/linker");
|
|
35
34
|
const doc_normalized_ast_1 = require("./doc-util/doc-normalized-ast");
|
|
35
|
+
const dfg_get_origin_1 = require("../dataflow/origin/dfg-get-origin");
|
|
36
|
+
const identify_link_to_last_call_relation_1 = require("../queries/catalog/call-context-query/identify-link-to-last-call-relation");
|
|
37
|
+
const doc_issue_1 = require("./doc-util/doc-issue");
|
|
38
|
+
const unnamed_call_handling_1 = require("../dataflow/internal/process/functions/call/unnamed-call-handling");
|
|
39
|
+
const environment_builder_1 = require("../../test/functionality/_helper/dataflow/environment-builder");
|
|
36
40
|
async function subExplanation(shell, { description, code, expectedSubgraph }) {
|
|
37
41
|
expectedSubgraph = await (0, doc_dfg_1.verifyExpectedSubgraph)(shell, code, expectedSubgraph);
|
|
38
42
|
const marks = [];
|
|
@@ -68,7 +72,7 @@ async function explanation({ shell, name, type, description, code, expectedSubgr
|
|
|
68
72
|
<a id='${name.toLowerCase().replaceAll(' ', '-')}'> </a>
|
|
69
73
|
### ${index}) ${name}
|
|
70
74
|
|
|
71
|
-
Type: \`${type}\`
|
|
75
|
+
Type: \`${type}\` (this is the numeric value of the bit-flag encountered when looking at the serialized vertex type)
|
|
72
76
|
|
|
73
77
|
${await subExplanation(shell, { name, description, code, expectedSubgraph })}
|
|
74
78
|
|
|
@@ -78,8 +82,8 @@ ${subExplanations.length > 0 ? await printAllSubExplanations(shell, subExplanati
|
|
|
78
82
|
function edgeTypeToId(edgeType) {
|
|
79
83
|
return (0, edge_1.edgeTypeToName)(edgeType).toLowerCase().replaceAll(' ', '-');
|
|
80
84
|
}
|
|
81
|
-
function linkEdgeName(edgeType) {
|
|
82
|
-
return `[\`${(0, edge_1.edgeTypeToName)(edgeType)}\`](#${edgeTypeToId(edgeType)})`;
|
|
85
|
+
function linkEdgeName(edgeType, page = '') {
|
|
86
|
+
return `[\`${(0, edge_1.edgeTypeToName)(edgeType)}\`](${page}#${edgeTypeToId(edgeType)})`;
|
|
83
87
|
}
|
|
84
88
|
async function getVertexExplanations(shell, vertexType) {
|
|
85
89
|
/* we use the map to ensure order easily :D */
|
|
@@ -155,6 +159,16 @@ In general, there may be many such edges, identifying every possible definition
|
|
|
155
159
|
${(0, doc_structure_1.details)('Example: Reads Edge Identifying Multiple Definitions (conditional)', await (0, doc_dfg_1.printDfGraphForCode)(shell, 'x <- 1\nif(u) x <- 2\nprint(x)', { mark: new Set([10, '10->0', '10->4']), codeOpen: true }))}
|
|
156
160
|
${(0, doc_structure_1.details)('Example: Reads Edge Identifying Multiple Definitions (loop)', await (0, doc_dfg_1.printDfGraphForCode)(shell, 'x <- 1\nfor(i in v) x <- 2\nprint(x)', { mark: new Set([11, '11->0', '11->5']), codeOpen: true }))}
|
|
157
161
|
${(0, doc_structure_1.details)('Example: Reads Edge Identifying Multiple Definitions (side-effect)', await (0, doc_dfg_1.printDfGraphForCode)(shell, 'f <- function() x <<- 2\nx <- 2\nif(u) f()\nprint(x)', { mark: new Set([16, '16->1', '16->7']), codeOpen: true }))}
|
|
162
|
+
|
|
163
|
+
${(0, doc_structure_1.block)({
|
|
164
|
+
type: 'IMPORTANT',
|
|
165
|
+
content: `
|
|
166
|
+
If you want to obtain the locations where a variable is defined, or read, or re-defined, refrain from tracking these details manually in the dataflow graph
|
|
167
|
+
as there are some edge-cases that require special attention.
|
|
168
|
+
In general, the ${(0, doc_types_1.shortLink)(dfg_get_origin_1.getOriginInDfg.name, vertexType.info)} function explained below in [working with the dataflow graph](${doc_files_1.FlowrWikiBaseRef}/Working%20with%20the%20Dataflow%20Graph) will help you to get the information you need.
|
|
169
|
+
`
|
|
170
|
+
})}
|
|
171
|
+
|
|
158
172
|
`,
|
|
159
173
|
code: 'x',
|
|
160
174
|
expectedSubgraph: (0, dataflowgraph_builder_1.emptyGraph)().use('1@x', 'x')
|
|
@@ -175,6 +189,12 @@ ${(0, doc_types_1.printHierarchy)({ program: vertexType.program, info: vertexTyp
|
|
|
175
189
|
The related function argument references are defined like this:
|
|
176
190
|
${(0, doc_types_1.printHierarchy)({ program: vertexType.program, info: vertexType.info, root: 'FunctionArgument' })}
|
|
177
191
|
|
|
192
|
+
There is another element of potential interest to you, the \`origin\` property which records how flowR created the respective function call.
|
|
193
|
+
These origins may hold the name of any processor that is part of the ${(0, doc_types_1.shortLink)('BuiltInProcessorMapper', vertexType.info)} to signal that the respective processor was responsible for creating the vertex.
|
|
194
|
+
The entry \`function\` signals that flowR used a processor for a user-defined function defined within the source code, \`unnamed\` signals that the function as an anonymous function definition.
|
|
195
|
+
However, in general, flowR may use any fitting handler as an origin. For example, within a access definition, flowR will correspondingly redefine the meaning of \`:=\` to that of the \`table:assign\`.
|
|
196
|
+
|
|
197
|
+
|
|
178
198
|
|
|
179
199
|
${(0, doc_structure_1.details)('Example: Simple Function Call (unresolved)', await (async () => {
|
|
180
200
|
const code = 'foo(x,3,y=3,)';
|
|
@@ -236,7 +256,7 @@ In this case, the call does not have a single ${linkEdgeName(edge_1.EdgeType.Cal
|
|
|
236
256
|
global beyond the scope of the given script. _flowR_ generally (theoretically at least) does not know if the call really refers to a built-in variable or function,
|
|
237
257
|
as any code that is not part of the analysis could cause the semantics to change.
|
|
238
258
|
However, it is (in most cases) safe to assume we call a builtin if there is a builtin function with the given name and if there is no ${linkEdgeName(edge_1.EdgeType.Calls)} edge attached to a call.
|
|
239
|
-
If you want to check the resolve targets, refer to
|
|
259
|
+
If you want to check the resolve targets, refer to ${(0, doc_types_1.shortLink)(resolve_by_name_1.resolveByName.name, vertexType.info)}.
|
|
240
260
|
`)}
|
|
241
261
|
|
|
242
262
|
${(0, doc_structure_1.details)('2) the function only resolves to definitions that are present in the program', `
|
|
@@ -326,11 +346,13 @@ Similarly, trying to resolve the name with \`${resolve_by_name_1.resolveByName.n
|
|
|
326
346
|
|
|
327
347
|
`)}
|
|
328
348
|
|
|
329
|
-
|
|
349
|
+
|
|
350
|
+
Similar to finding the definitions read by a variable use, please use the ${(0, doc_types_1.shortLink)(linker_1.getAllFunctionCallTargets.name, vertexType.info)} function to find all possible definitions of a function call,
|
|
351
|
+
as explained in the [working with the dataflow graph](${doc_files_1.FlowrWikiBaseRef}/Working%20with%20the%20Dataflow%20Graph) section.`
|
|
330
352
|
})}
|
|
331
353
|
|
|
332
354
|
Function calls are the most complicated mechanism in R as essentially everything is a function call.
|
|
333
|
-
Even **control structures** like \`if(p) a else b\` are desugared into function calls (e.g., as \`if\`(p, a, b)).
|
|
355
|
+
Even **control structures** like \`if(p) a else b\` are desugared into function calls (e.g., as \`\` \`if\`(p, a, b) \`\`).
|
|
334
356
|
${(0, doc_structure_1.details)('Example: <code>if</code> as a Function Call', await (0, doc_dfg_1.printDfGraphForCode)(shell, 'if(p) a else b'))}
|
|
335
357
|
|
|
336
358
|
Similarly, you should be aware of calls to **anonymous functions**, which may appear given directly (e.g. as \`(function() 1)()\`) or indirectly, with code
|
|
@@ -339,6 +361,21 @@ ${(0, doc_structure_1.details)('Example: Anonymous Function Call (given directly
|
|
|
339
361
|
|
|
340
362
|
${(0, doc_structure_1.details)('Example: Anonymous Function Call (given indirectly)', await (0, doc_dfg_1.printDfGraphForCode)(shell, 'foo <- function() return(function() 3)\nfoo()()', { mark: new Set([12, '12->4']) }))}
|
|
341
363
|
|
|
364
|
+
${(0, doc_structure_1.block)({
|
|
365
|
+
type: 'NOTE',
|
|
366
|
+
content: `Now you might be asking yourself how to differentiate anonymous and named functions and what you have to keep in mind when working with them?
|
|
367
|
+
|
|
368
|
+
Unnamed functions have an array of signatures which you can use to identify them.
|
|
369
|
+
But in short - the \`origin\` attribute of the ${(0, doc_types_1.shortLink)('DataflowGraphVertexFunctionCall', vertexType.info)} is \`${unnamed_call_handling_1.UnnamedFunctionCallOrigin}\`.
|
|
370
|
+
Please be aware that unnamed functions still have a \`name\` property to give it a unique identifier that can be used for debugging and reference.
|
|
371
|
+
This name _always_ starts with \`${unnamed_call_handling_1.UnnamedFunctionCallPrefix}\`.
|
|
372
|
+
|
|
373
|
+
To identify these calls please do not rely on the [Normalized AST](${doc_files_1.FlowrWikiBaseRef}/Normalized%20AST). An expression like \`1 + 1\` will be correctly
|
|
374
|
+
identified as a syntactical binary operation. Yet, from a dataflow/semantic perspective this is equivalent to \`\` \`+\`(1, 1) \`\` (which is a named function call and marked as such in the dataflow graph).
|
|
375
|
+
To know which function is called, please rely on the ${linkEdgeName(edge_1.EdgeType.Calls)} edge.
|
|
376
|
+
`
|
|
377
|
+
})}
|
|
378
|
+
|
|
342
379
|
Another interesting case is a function with **side effects**, most prominently with the super-assignment \`<<-\`.
|
|
343
380
|
In this case, you may encounter the ${linkEdgeName(edge_1.EdgeType.SideEffectOnCall)} as exemplified below.
|
|
344
381
|
${(0, doc_structure_1.details)('Example: Function Call with a Side-Effect', await (0, doc_dfg_1.printDfGraphForCode)(shell, 'f <- function() x <<- 3\n f()', { mark: new Set([8, '1->8']) }))}
|
|
@@ -495,8 +532,9 @@ ${(0, doc_structure_1.block)({
|
|
|
495
532
|
content: `
|
|
496
533
|
A ${linkEdgeName(edge_1.EdgeType.Reads)} edge is not a transitive closure and only links the "directly read" definition(s).
|
|
497
534
|
Our abstract domains resolving transitive ${linkEdgeName(edge_1.EdgeType.Reads)} edges (and for that matter, following ${linkEdgeName(edge_1.EdgeType.Returns)} as well)
|
|
498
|
-
are currently tailored to what we need in _flowR_. Hence, we offer a function like ${(0, doc_types_1.shortLink)(linker_1.getAllFunctionCallTargets.name, vertexType.info)}
|
|
499
|
-
as well as ${(0, doc_types_1.shortLink)(resolve_by_name_1.resolvesToBuiltInConstant.name, vertexType.info)}
|
|
535
|
+
are currently tailored to what we need in _flowR_. Hence, we offer a function like ${(0, doc_types_1.shortLink)(linker_1.getAllFunctionCallTargets.name, vertexType.info)},
|
|
536
|
+
as well as ${(0, doc_types_1.shortLink)(resolve_by_name_1.resolvesToBuiltInConstant.name, vertexType.info)} which do this for specific cases.
|
|
537
|
+
Refer to ${(0, doc_types_1.shortLink)(dfg_get_origin_1.getOriginInDfg.name, vertexType.info)} for a more general solution, as explained in [working with the dataflow graph](${doc_files_1.FlowrWikiBaseRef}/Working%20with%20the%20Dataflow%20Graph).
|
|
500
538
|
|
|
501
539
|
${(0, doc_structure_1.details)('Example: Multi-Level Reads', await (0, doc_dfg_1.printDfGraphForCode)(shell, 'x <- 3\ny <- x\nprint(y)', { mark: new Set(['9->7', '7->3', '4->0']) }))}
|
|
502
540
|
|
|
@@ -505,6 +543,10 @@ Similarly, ${linkEdgeName(edge_1.EdgeType.Reads)} can be cyclic, for example in
|
|
|
505
543
|
${(0, doc_structure_1.details)('Example: Cyclic Reads', await (0, doc_dfg_1.printDfGraphForCode)(shell, 'for(i in v) x <- x + 1', { mark: new Set(['3->2']) }))}
|
|
506
544
|
`
|
|
507
545
|
})}
|
|
546
|
+
|
|
547
|
+
Reads edges may point to built-in definitions as well, to signal that something relates to a built-in element of flowR.
|
|
548
|
+
Their targets are not part of the ${(0, doc_types_1.shortLink)(graph_1.DataflowGraph.name, vertexType.info)} but only markers to signal that the respective definition is a built-in.
|
|
549
|
+
|
|
508
550
|
|
|
509
551
|
Please refer to the explanation of the respective vertices for more information.
|
|
510
552
|
`,
|
|
@@ -526,7 +568,7 @@ Please refer to the explanation of the respective vertices for more information.
|
|
|
526
568
|
name: 'DefinedBy Edge', /* concat for link generation */
|
|
527
569
|
type: edge_1.EdgeType.DefinedBy,
|
|
528
570
|
description: `
|
|
529
|
-
The source vertex is usually a [\`
|
|
571
|
+
The source vertex is usually a [\`variable definition\`](#variable-definition-vertex) linking the defined symbol to the entry point of the resulting side.
|
|
530
572
|
${(0, doc_structure_1.details)('In general, this does not have to be the right hand side of the operator.', await (0, doc_dfg_1.printDfGraphForCode)(shell, '3 -> x', { mark: new Set([0]) }))}
|
|
531
573
|
|
|
532
574
|
However, nested definitions can carry it (in the nested case, \`x\` is defined by the return value of <code>\\\`<-\\\`(y, z)</code>). Additionally, we link the assignment function.
|
|
@@ -549,7 +591,8 @@ However, nested definitions can carry it (in the nested case, \`x\` is defined b
|
|
|
549
591
|
shell,
|
|
550
592
|
name: 'Calls Edge',
|
|
551
593
|
type: edge_1.EdgeType.Calls,
|
|
552
|
-
description:
|
|
594
|
+
description: `Link the [function call](#function-call-vertex) to the [function definition](#function-definition-vertex) that is called. To find all called definitions,
|
|
595
|
+
please use the ${(0, doc_types_1.shortLink)(dfg_get_origin_1.getOriginInDfg.name, vertexType.info)} function, as explained in [working with the dataflow graph](${doc_files_1.FlowrWikiBaseRef}/Working%20with%20the%20Dataflow%20Graph).`,
|
|
553
596
|
code: 'foo <- function() {}\nfoo()',
|
|
554
597
|
expectedSubgraph: (0, dataflowgraph_builder_1.emptyGraph)().calls('2@foo', '1@function')
|
|
555
598
|
}, []]);
|
|
@@ -557,9 +600,40 @@ However, nested definitions can carry it (in the nested case, \`x\` is defined b
|
|
|
557
600
|
shell,
|
|
558
601
|
name: 'Returns Edge',
|
|
559
602
|
type: edge_1.EdgeType.Returns,
|
|
560
|
-
description:
|
|
603
|
+
description: `Link the [function call](#function-call-vertex) to the exit points of the target definition (this may incorporate the call-context).
|
|
604
|
+
As you can see in the example, this happens for user-defined functions (like \`foo\`) as well as for built-in functions (like \`<-\`).
|
|
605
|
+
However, these edges are specific to scenarios in which flowR knows that a specific element is returned.
|
|
606
|
+
For contrast, compare this to a use of, for example, \`+\`:
|
|
607
|
+
|
|
608
|
+
${(0, doc_structure_1.details)('Example: No returns edge for +', await (0, doc_dfg_1.printDfGraphForCode)(shell, '1 + 1'))}
|
|
609
|
+
|
|
610
|
+
Here, we do not get a ${linkEdgeName(edge_1.EdgeType.Returns)} edge as this function call creates a new value based on its arguments.
|
|
611
|
+
In these scenarios you should rely on the \`args\` property of the ${(0, doc_types_1.shortLink)('DataflowGraphVertexFunctionCall', vertexType.info)}
|
|
612
|
+
and use the arguments to calculate what you need to know. Alternatively, you can track the ${linkEdgeName(edge_1.EdgeType.Argument)} edges.
|
|
613
|
+
|
|
614
|
+
In general, the ${linkEdgeName(edge_1.EdgeType.Returns)} edge already does most of the heavy lifting for you, by respecting control flow influences and
|
|
615
|
+
(as long as flowR is able to detect it) dead code.
|
|
616
|
+
|
|
617
|
+
${(0, doc_structure_1.details)('Example: Tricky Returns', `We show the _simplified_ DFG for simplicity and highlight all ${linkEdgeName(edge_1.EdgeType.Returns)} edges involved in tracking the return of a call to \`f\` (as ${linkEdgeName(edge_1.EdgeType.Returns)} are never transitive and must hence be followed):\n` +
|
|
618
|
+
await (0, doc_dfg_1.printDfGraphForCode)(shell, 'f <- function() { if(u) { return(3); 2 } else 42 }\nf()', {
|
|
619
|
+
simplified: true,
|
|
620
|
+
mark: new Set(['19->15', '15->14', '14->12', '14->11', '11->9', '9->7'])
|
|
621
|
+
})
|
|
622
|
+
+ '\n\n Note, that the `2` should be completely absent of the dataflow graph (recognized as dead code).')}
|
|
623
|
+
<br/>
|
|
624
|
+
|
|
625
|
+
${(0, doc_structure_1.block)({
|
|
626
|
+
type: 'NOTE',
|
|
627
|
+
content: `You might find it an inconvenience that there is no ${linkEdgeName(edge_1.EdgeType.Returns)} edge for _every_ function call.
|
|
628
|
+
If there is particular function for which you think flowR should be able to detect the return, please open a [new issue](${doc_issue_1.NewIssueUrl}).
|
|
629
|
+
Yet the problem of flowR not tracking returns for functions that create new/transform existing values is a fundamental design decision — if this irritates you ~~you may be eligible for compensation~~, you may be interested in an
|
|
630
|
+
alternative with the [Control Flow Graph](${doc_files_1.FlowrWikiBaseRef}/Control%20Flow%20Graph#cfg-exit-points) which not just tracks all possible execution orders of the program,
|
|
631
|
+
but also the exit points of _all_ function calls.
|
|
632
|
+
`
|
|
633
|
+
})}
|
|
634
|
+
`,
|
|
561
635
|
code: 'foo <- function() x\nfoo()',
|
|
562
|
-
expectedSubgraph: (0, dataflowgraph_builder_1.emptyGraph)().returns('2@foo', '1@x')
|
|
636
|
+
expectedSubgraph: (0, dataflowgraph_builder_1.emptyGraph)().returns('2@foo', '1@x').returns('1@<-', '1@foo').argument('1@<-', '1@foo')
|
|
563
637
|
}, []]);
|
|
564
638
|
const lateBindingExample = `
|
|
565
639
|
f <- function() x
|
|
@@ -573,7 +647,7 @@ f()
|
|
|
573
647
|
type: edge_1.EdgeType.DefinesOnCall,
|
|
574
648
|
description: `*This edge is usually joined with ${linkEdgeName(edge_1.EdgeType.DefinedByOnCall)}!*
|
|
575
649
|
|
|
576
|
-
Links an
|
|
650
|
+
Links an argument to whichever parameter they cause to be defined if the related function call is invoked.
|
|
577
651
|
|
|
578
652
|
In the context of functions which access their closure environment these edges play another tricky role as there are many cases
|
|
579
653
|
made more difficult by R's way of allowing closure environments to later receive variables.
|
|
@@ -689,18 +763,30 @@ async function getText(shell) {
|
|
|
689
763
|
});
|
|
690
764
|
return `${(0, doc_auto_gen_1.autoGenHeader)({ filename: module.filename, purpose: 'dataflow graph', rVersion: rversion })}
|
|
691
765
|
|
|
692
|
-
This page briefly summarizes flowR's dataflow graph, represented by the ${(0, doc_types_1.shortLink)(graph_1.DataflowGraph.name, vertexType.info)}.
|
|
766
|
+
This page briefly summarizes flowR's dataflow graph, represented by the ${(0, doc_types_1.shortLink)(graph_1.DataflowGraph.name, vertexType.info)} class within the code.
|
|
693
767
|
In case you want to manually build such a graph (e.g., for testing), you can use the ${(0, doc_types_1.shortLink)(dataflowgraph_builder_1.DataflowGraphBuilder.name, vertexType.info)}.
|
|
694
|
-
|
|
768
|
+
In summary, we discuss the following topics:
|
|
769
|
+
|
|
770
|
+
- [Vertices](#vertices)
|
|
771
|
+
- [Edges](#edges)
|
|
772
|
+
- [Control Dependencies](#control-dependencies)
|
|
773
|
+
- [Dataflow Information](#dataflow-information)
|
|
774
|
+
- [Unknown Side Effects](#unknown-side-effects)
|
|
775
|
+
- [Working with the Dataflow Graph](#dfg-working)
|
|
695
776
|
|
|
696
|
-
Please be aware that the accompanied [dataflow information](#dataflow-information) returned by _flowR_ contains things besides the graph,
|
|
777
|
+
Please be aware that the accompanied [dataflow information](#dataflow-information) (${(0, doc_types_1.shortLink)('DataflowInformation', vertexType.info)}) returned by _flowR_ contains things besides the graph,
|
|
697
778
|
like the entry and exit points of the subgraphs, and currently active references (see [below](#dataflow-information)).
|
|
698
779
|
Additionally, you may be interested in the set of [Unknown Side Effects](#unknown-side-effects) marking calls which _flowR_ is unable to handle correctly.
|
|
699
780
|
|
|
781
|
+
Potentially, you are interested in another perspective that flowR provides, the [control flow graph](${doc_files_1.FlowrWikiBaseRef}/Control%20Flow%20Graph), so please check the correpsonding
|
|
782
|
+
wiki page if you are unsure.
|
|
783
|
+
|
|
700
784
|
> [!TIP]
|
|
701
785
|
> If you want to investigate the dataflow graph,
|
|
702
786
|
> you can either use the [Visual Studio Code extension](${doc_files_1.FlowrGithubBaseRef}/vscode-flowr) or the ${(0, doc_cli_option_1.getReplCommand)('dataflow*')}
|
|
703
|
-
> command in the REPL (see the [Interface wiki page](${doc_files_1.FlowrWikiBaseRef}/Interface) for more information).
|
|
787
|
+
> command in the REPL (see the [Interface wiki page](${doc_files_1.FlowrWikiBaseRef}/Interface) for more information).
|
|
788
|
+
> There is also a simplified perspective available with ${(0, doc_cli_option_1.getReplCommand)('dataflowsimple*')} that does not show everything but is easier to read.
|
|
789
|
+
> When using _flowR_ as a library, you may use the functions in ${(0, doc_files_1.getFilePathMd)('../util/mermaid/dfg.ts')}.
|
|
704
790
|
>
|
|
705
791
|
> If you receive a dataflow graph in its serialized form (e.g., by talking to a [_flowR_ server](${doc_files_1.FlowrWikiBaseRef}/Interface)), you can use ${(0, doc_types_1.shortLink)(`${graph_1.DataflowGraph.name}::${graph_1.DataflowGraph.fromJson.name}`, vertexType.info, true, 'i')} to retrieve the graph from the JSON representation.
|
|
706
792
|
|
|
@@ -709,7 +795,8 @@ ${await (0, doc_dfg_1.printDfGraphForCode)(shell, 'x <- 3\ny <- x + 1\ny')}
|
|
|
709
795
|
|
|
710
796
|
The above dataflow graph showcases the general gist. We define a dataflow graph as a directed graph G = (V, E), differentiating between ${(0, doc_data_dfg_util_1.getAllVertices)().length} types of vertices V and
|
|
711
797
|
${(0, doc_data_dfg_util_1.getAllEdges)().length} types of edges E allowing each vertex to have a single, and each edge to have multiple distinct types.
|
|
712
|
-
Additionally, every node may have links to its [control dependencies](#control-dependencies) (which you may view as a ${(0, text_1.nth)((0, doc_data_dfg_util_1.getAllEdges)().length + 1)} edge type,
|
|
798
|
+
Additionally, every node may have links to its [control dependencies](#control-dependencies) (which you may view as a ${(0, text_1.nth)((0, doc_data_dfg_util_1.getAllEdges)().length + 1)} edge type,
|
|
799
|
+
although they are explicitly no data dependency and relate to the [Control Flow Graph](${doc_files_1.FlowrWikiBaseRef}/Control%20Flow%20Graph)).
|
|
713
800
|
|
|
714
801
|
<details open>
|
|
715
802
|
|
|
@@ -748,18 +835,22 @@ ${(0, doc_general_1.prefixLines)((0, doc_code_1.codeBlock)('ts', 'const node = g
|
|
|
748
835
|
> In case you just need the name (\`lexeme\`) of the respective vertex, ${(0, doc_types_1.shortLink)(node_id_1.recoverName.name, vertexType.info)} can help you out:
|
|
749
836
|
${(0, doc_general_1.prefixLines)((0, doc_code_1.codeBlock)('ts', `const name = ${node_id_1.recoverName.name}(id, graph.idMap);`), '> ')}
|
|
750
837
|
|
|
751
|
-
|
|
838
|
+
${(0, doc_structure_1.section)('Vertices', 2, 'vertices')}
|
|
839
|
+
|
|
840
|
+
1. ${(0, doc_data_dfg_util_1.getAllVertices)().map(([k, v], index) => `[\`${k}\`](#${index + 1}-${v.toLowerCase().replace(/\s/g, '-')}-vertex)`).join('\n1. ')}
|
|
752
841
|
|
|
753
842
|
${await getVertexExplanations(shell, vertexType)}
|
|
754
843
|
|
|
755
|
-
|
|
844
|
+
${(0, doc_structure_1.section)('Edges', 2, 'edges')}
|
|
845
|
+
|
|
846
|
+
1. ${(0, doc_data_dfg_util_1.getAllEdges)().map(([k, v], index) => `[\`${k}\` (${v})](#${index + 1}-${k.toLowerCase().replace(/\s/g, '-')}-edge)`).join('\n1. ')}
|
|
756
847
|
|
|
757
848
|
${await getEdgesExplanations(shell, vertexType)}
|
|
758
849
|
|
|
759
|
-
|
|
850
|
+
${(0, doc_structure_1.section)('Control Dependencies', 2, 'control-dependencies')}
|
|
760
851
|
|
|
761
852
|
Each vertex may have a list of active control dependencies.
|
|
762
|
-
They hold the
|
|
853
|
+
They hold the ${(0, doc_types_1.shortLink)('NodeId', vertexType.info)} of all nodes that effect if the current vertex is part of the execution or not,
|
|
763
854
|
and a boolean flag \`when\` to indicate if the control dependency is active when the condition is \`true\` or \`false\`.
|
|
764
855
|
|
|
765
856
|
As an example, consider the following dataflow graph:
|
|
@@ -775,7 +866,8 @@ ${(0, doc_structure_1.details)('Example: Multiple Vertices (Assignment)', await
|
|
|
775
866
|
${(0, doc_structure_1.details)('Example: Multiple Vertices (Arithmetic Expression)', await (0, doc_dfg_1.printDfGraphForCode)(shell, 'if(p) 3 + 2'))}
|
|
776
867
|
${(0, doc_structure_1.details)('Example: Nested Conditionals', await (0, doc_dfg_1.printDfGraphForCode)(shell, 'if(x) { if(y) a else b } else c'))}
|
|
777
868
|
|
|
778
|
-
|
|
869
|
+
|
|
870
|
+
${(0, doc_structure_1.section)('Dataflow Information', 2, 'dataflow-information')}
|
|
779
871
|
|
|
780
872
|
Using _flowR's_ code interface (see the [Interface](${doc_files_1.FlowrWikiBaseRef}/Interface) wiki page for more), you can generate the dataflow information
|
|
781
873
|
for a given piece of R code (in this case \`x <- 1; x + 1\`) as follows (using the ${(0, doc_types_1.shortLink)(shell_1.RShell.name, vertexType.info)} and the ${(0, doc_types_1.shortLink)(pipeline_executor_1.PipelineExecutor.name, vertexType.info)} classes):
|
|
@@ -877,6 +969,69 @@ Additionally, we express this by a ${linkEdgeName(edge_1.EdgeType.Reads)} edge.
|
|
|
877
969
|
`;
|
|
878
970
|
})()}
|
|
879
971
|
|
|
972
|
+
${(0, doc_structure_1.section)('Working with the Dataflow Graph', 2, 'dfg-working')}
|
|
973
|
+
|
|
974
|
+
The ${(0, doc_types_1.shortLink)('DataflowInformation', vertexType.info)} is the core result of _flowR_ and summarizes a lot of information.
|
|
975
|
+
Depending on what you are interested in, there exists a plethora of functions and queries to help you out, answering the most important questions:
|
|
976
|
+
|
|
977
|
+
* 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
|
+
* 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
|
+
* ${(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)(resolve_by_name_1.resolveValueOfVariable.name, vertexType.info)} and ${(0, doc_types_1.shortLink)(resolve_by_name_1.resolveIdToValue.name, vertexType.info)} to resolve the value of a variable or id (if possible, see [below](#dfg-resolving-values))
|
|
981
|
+
* ${(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
|
+
* ${(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
|
+
* ${(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))
|
|
984
|
+
|
|
985
|
+
Some of these functions have been explained in their respective wiki pages. However, some are part of the [Dataflow Graph API](${doc_files_1.FlowrWikiBaseRef}/Dataflow%20Graph%20API) and so we explain them here.
|
|
986
|
+
|
|
987
|
+
${(0, doc_structure_1.section)('Resolving Values', 3, 'dfg-resolving-values')}
|
|
988
|
+
|
|
989
|
+
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
|
+
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
|
+
${(0, doc_types_1.shortLink)(resolve_by_name_1.resolveValueOfVariable.name, vertexType.info)} provides an environment-sensitive (see ${(0, doc_types_1.shortLink)('REnvironmentInformation', vertexType.info)})
|
|
993
|
+
value resolution, while ${(0, doc_types_1.shortLink)(resolve_by_name_1.resolveIdToValue.name, vertexType.info)} provides a more general, but potentially less precise resolution independent of the current state.
|
|
994
|
+
|
|
995
|
+
${(0, doc_structure_1.section)('Assessing Edges', 3, 'dfg-assess-edge')}
|
|
996
|
+
|
|
997
|
+
The [edges](#edges) of the dataflow graph use bitmasks to represent an edge with multiple types. While this compacts the representation greatly, it makes it
|
|
998
|
+
difficult to check whether a given edge is a read edge.
|
|
999
|
+
Consider the following example:
|
|
1000
|
+
|
|
1001
|
+
${await (0, doc_dfg_1.printDfGraphForCode)(shell, 'print(x)', { mark: new Set(['3->1']) })}
|
|
1002
|
+
|
|
1003
|
+
Retrieving the _types_ of the edge from the print call to its argument returns:
|
|
1004
|
+
${await (async () => {
|
|
1005
|
+
const dfg = await (0, default_pipelines_1.createDataflowPipeline)(shell, {
|
|
1006
|
+
request: (0, retriever_1.requestFromInput)('print(x)')
|
|
1007
|
+
}).allRemainingSteps();
|
|
1008
|
+
const edge = dfg.dataflow.graph.outgoingEdges(3);
|
|
1009
|
+
if (edge) {
|
|
1010
|
+
const wanted = edge.get(1);
|
|
1011
|
+
if (wanted) {
|
|
1012
|
+
return '`' + wanted.types + '`';
|
|
1013
|
+
}
|
|
1014
|
+
}
|
|
1015
|
+
new Error('Could not find edge');
|
|
1016
|
+
})()}—which is usually not very helpful.
|
|
1017
|
+
You can use ${(0, doc_types_1.shortLink)(edge_1.splitEdgeTypes.name, vertexType.info)} to get the individual bitmasks of all included types, and
|
|
1018
|
+
${(0, doc_types_1.shortLink)(edge_1.edgeIncludesType.name, vertexType.info)} to check whether a specific type (or one of a collection of types) is included in the edge.
|
|
1019
|
+
|
|
1020
|
+
${(0, doc_structure_1.section)('Handling Origins', 3, 'dfg-handling-origins')}
|
|
1021
|
+
|
|
1022
|
+
If you are writing another analysis on top of the dataflow graph, you probably want to know all definitions that serve as the source of a read, all functions
|
|
1023
|
+
that are called by an invocation, and more.
|
|
1024
|
+
For this, the ${(0, doc_types_1.shortLink)(dfg_get_origin_1.getOriginInDfg.name, vertexType.info)} function provides you with a collection of ${(0, doc_types_1.shortLink)('Origin', vertexType.info)} objects:
|
|
1025
|
+
|
|
1026
|
+
${(0, doc_types_1.printHierarchy)({ program: vertexType.program, info: vertexType.info, root: 'Origin', openTop: true })}
|
|
1027
|
+
|
|
1028
|
+
Their respective uses are documented alongside their implementation:
|
|
1029
|
+
|
|
1030
|
+
${['SimpleOrigin', 'FunctionCallOrigin', 'BuiltInFunctionOrigin'].sort().map(key => `- ${(0, doc_types_1.shortLink)(`${key}`, vertexType.info)}\\\n${(0, doc_types_1.getDocumentationForType)(`${key}`, vertexType.info)}`).join('\n')}
|
|
1031
|
+
|
|
1032
|
+
Please note, the current structure of this function is biased by what implementations already exist in flowR.
|
|
1033
|
+
Hence, we do not just track definitions and constants, but also the origins of function calls, albeit we do not yet track the origins of values (only resorting to
|
|
1034
|
+
a constant origin). If you are confused by this please start a discussion—in a way we are still deciding on a good API for this.
|
|
880
1035
|
|
|
881
1036
|
`;
|
|
882
1037
|
})()}
|
|
@@ -24,7 +24,7 @@ async function getText(shell) {
|
|
|
24
24
|
return `${(0, doc_auto_gen_1.autoGenHeader)({ filename: module.filename, purpose: 'engines', rVersion: rversion })}
|
|
25
25
|
|
|
26
26
|
To analyze R scripts, flowR needs to parse the R code and for that, we require a parser.
|
|
27
|
-
Originally, flowR shipped with
|
|
27
|
+
Originally, flowR shipped with an ${(0, doc_types_1.shortLink)(shell_1.RShell.name, types.info)}, an asynchronous interface to the R interpreter, still available today.
|
|
28
28
|
Later we extended this with the ${(0, doc_types_1.shortLink)(shell_executor_1.RShellExecutor.name, types.info)}, the synchronous counterpart to the ${(0, doc_types_1.shortLink)(shell_1.RShell.name, types.info)}.
|
|
29
29
|
However, these interfaces are relatively slow as they require communication with an underlying R interpreter.
|
|
30
30
|
Using [tree-sitter](https://tree-sitter.github.io/tree-sitter/), with its [node bindings](https://github.com/tree-sitter/node-tree-sitter)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const log_1 = require("../../test/functionality/_helper/log");
|
|
4
|
+
const doc_auto_gen_1 = require("./doc-util/doc-auto-gen");
|
|
5
|
+
const doc_files_1 = require("./doc-util/doc-files");
|
|
6
|
+
const doc_code_1 = require("./doc-util/doc-code");
|
|
7
|
+
function print() {
|
|
8
|
+
return `${(0, doc_auto_gen_1.autoGenHeader)({ filename: module.filename, purpose: 'frequently asked questions' })}
|
|
9
|
+
|
|
10
|
+
## 💮 *flowR* FAQ
|
|
11
|
+
|
|
12
|
+
### 🧑💻 *flowR* Development
|
|
13
|
+
|
|
14
|
+
${qAndA('What are test labels and how do they work?', `
|
|
15
|
+
Tests are labeled based on the *flowR* capabilities that they test for. The list of supported capabilities can be found on the [Capabilities](${doc_files_1.FlowrWikiBaseRef}/Capabilities) wiki page. For more extensive information on test labels, see the [test labels wiki section](${doc_files_1.FlowrWikiBaseRef}/Linting-and-Testing#test-labels).
|
|
16
|
+
`)}
|
|
17
|
+
|
|
18
|
+
${qAndA('How do I generate mermaid diagrams?', `
|
|
19
|
+
There are several ways to generate mermaid diagrams based on the input data that you want to use.
|
|
20
|
+
- From the AST (abstract syntax tree): ${(0, doc_files_1.getFilePathMd)('../util/mermaid/ast.ts')}
|
|
21
|
+
- From the CFG (control flow graph): ${(0, doc_files_1.getFilePathMd)('../util/mermaid/cfg.ts')}
|
|
22
|
+
- From the DFG (dataflow graph): ${(0, doc_files_1.getFilePathMd)('../util/mermaid/dfg.ts')}
|
|
23
|
+
`)}
|
|
24
|
+
|
|
25
|
+
${qAndA('How do I create new wiki pages?', `
|
|
26
|
+
To create an automatically generated wiki page, you can follow these steps:
|
|
27
|
+
- Createa a new file in \`src/documentation\` with a name like \`print-my-page-wiki.ts\`.
|
|
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
|
+
- 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
|
+
|
|
31
|
+
You can test your page by piping the wiki generation script to a file. For example, you can run the following command:
|
|
32
|
+
${(0, doc_code_1.codeBlock)('shell', 'npm run --silent wiki:my-page > __my-page.md')}
|
|
33
|
+
`)}
|
|
34
|
+
Remember not to commit this file, as it's only meant for testing.
|
|
35
|
+
|
|
36
|
+
## 🇷 R FAQ
|
|
37
|
+
|
|
38
|
+
### 📦 R Packages
|
|
39
|
+
|
|
40
|
+
${qAndA('What is the R prelude and R base package?', `
|
|
41
|
+
The base package contains lots of base functions like \`source\` for example.
|
|
42
|
+
The R prelude includes the base package along with several other packages.
|
|
43
|
+
Packages that were loaded by the prelude can be called without prefixing the function call with the package name and the \`::\` operator.
|
|
44
|
+
|
|
45
|
+
The packages loaded by the R prelude can be seen in the \`attached base packages\` sections in the output of \`sessionInfo()\`.
|
|
46
|
+
`)}
|
|
47
|
+
|
|
48
|
+
${qAndA('How to get documentation for a function or package?', `
|
|
49
|
+
There are a couple of ways to get documentation for a function or package.
|
|
50
|
+
|
|
51
|
+
🖥️ Firstly, if you have already installed the package the function originated from you can simply run \`?<package name>::<function name>\` in an R session to print the
|
|
52
|
+
relevant documentation. If you don't know the origin of the package, you can use
|
|
53
|
+
\`??<function name>\` in an R shell to fuzzy find all documentations containing
|
|
54
|
+
\`<function name>\` or something similar.
|
|
55
|
+
|
|
56
|
+
🌐 Secondly, if you don't have or don't want to install the package you can simply google the fully qualified name of the function. Good sources include \`rdrr.io\`
|
|
57
|
+
or \`rdocumentation.org\`. Additionally, the package documentation PDF can also
|
|
58
|
+
be downloaded directly from \`cran\`.
|
|
59
|
+
`)}
|
|
60
|
+
|
|
61
|
+
`.trim();
|
|
62
|
+
}
|
|
63
|
+
function qAndA(question, answer) {
|
|
64
|
+
return `<details>
|
|
65
|
+
<summary><strong>${question}</strong></summary>
|
|
66
|
+
|
|
67
|
+
${answer.trim()}
|
|
68
|
+
|
|
69
|
+
</details>`;
|
|
70
|
+
}
|
|
71
|
+
if (require.main === module) {
|
|
72
|
+
(0, log_1.setMinLevelOfAllLogs)(6 /* LogLevel.Fatal */);
|
|
73
|
+
console.log(print());
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=print-faq-wiki.js.map
|
|
@@ -17,7 +17,7 @@ const doc_repl_1 = require("./doc-util/doc-repl");
|
|
|
17
17
|
const doc_dfg_1 = require("./doc-util/doc-dfg");
|
|
18
18
|
const config_1 = require("../config");
|
|
19
19
|
const schema_1 = require("../util/schema");
|
|
20
|
-
const ansi_1 = require("../util/ansi");
|
|
20
|
+
const ansi_1 = require("../util/text/ansi");
|
|
21
21
|
const flowr_main_options_1 = require("../cli/flowr-main-options");
|
|
22
22
|
const doc_issue_1 = require("./doc-util/doc-issue");
|
|
23
23
|
const pipeline_executor_1 = require("../core/pipeline-executor");
|
|
@@ -203,6 +203,7 @@ ${(0, doc_code_1.codeBlock)('json', JSON.stringify({
|
|
|
203
203
|
engines: [{ type: 'r-shell' }],
|
|
204
204
|
solver: {
|
|
205
205
|
variables: config_1.VariableResolve.Alias,
|
|
206
|
+
evalStrings: true,
|
|
206
207
|
pointerTracking: true,
|
|
207
208
|
resolveSource: {
|
|
208
209
|
dropPaths: config_1.DropPathsOption.No,
|